]> granicus.if.org Git - postgresql/commitdiff
Remove dependency on error ordering in isolation tests
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 27 Sep 2011 19:08:31 +0000 (16:08 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 27 Sep 2011 19:53:35 +0000 (16:53 -0300)
We now report errors reported by the just-unblocked and unblocking
transactions identically; this should fix relatively common buildfarm
failures reported by animals that are failing the "wrong" session.

src/test/isolation/expected/fk-deadlock.out
src/test/isolation/expected/fk-deadlock2.out
src/test/isolation/expected/fk-deadlock2_1.out
src/test/isolation/expected/fk-deadlock2_2.out [deleted file]
src/test/isolation/expected/fk-deadlock_1.out
src/test/isolation/isolationtester.c
src/test/isolation/isolationtester.h
src/test/isolation/specparse.y

index 2f4f71122e814eff315ab320eb6e5965a4d073e7..36813f11f51753584b5c7603586af884a364a011 100644 (file)
@@ -23,7 +23,7 @@ step s2i: INSERT INTO child VALUES (2, 1);
 step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
 step s2u: UPDATE parent SET aux = 'baz';
 step s1u: <... completed>
-ERROR:  deadlock detected
+error in steps s2u s1u: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -32,8 +32,8 @@ step s1i: INSERT INTO child VALUES (1, 1);
 step s2i: INSERT INTO child VALUES (2, 1);
 step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
 step s1u: UPDATE parent SET aux = 'bar';
-ERROR:  deadlock detected
 step s2u: <... completed>
+error in steps s1u s2u: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -43,7 +43,7 @@ step s1i: INSERT INTO child VALUES (1, 1);
 step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
 step s2u: UPDATE parent SET aux = 'baz';
 step s1u: <... completed>
-ERROR:  deadlock detected
+error in steps s2u s1u: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -52,8 +52,8 @@ step s2i: INSERT INTO child VALUES (2, 1);
 step s1i: INSERT INTO child VALUES (1, 1);
 step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
 step s1u: UPDATE parent SET aux = 'bar';
-ERROR:  deadlock detected
 step s2u: <... completed>
+error in steps s1u s2u: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
index 18015408161aa3655e3ddf916e6a15e2ef4f0a32..2d8e5e5b25f268bfd5da68893d07a9058b5e98ab 100644 (file)
@@ -23,7 +23,7 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -33,7 +33,7 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -42,8 +42,8 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -52,8 +52,8 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -63,7 +63,7 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -73,7 +73,7 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -82,8 +82,8 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -92,8 +92,8 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
index 8ccc24a2abf74ec5ba30749395ee45e5d1d1bc27..30c4c998631afcf42ab122fada730b6d0bc2b988 100644 (file)
@@ -14,7 +14,7 @@ step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1c: COMMIT;
 step s2u1: <... completed>
-ERROR:  could not serialize access due to concurrent update
+error in steps s1c s2u1: ERROR:  could not serialize access due to concurrent update
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 ERROR:  current transaction is aborted, commands ignored until end of transaction block
 step s2c: COMMIT;
@@ -25,7 +25,7 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -35,7 +35,7 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -44,8 +44,8 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -54,8 +54,8 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -65,7 +65,7 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -75,7 +75,7 @@ step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u2: <... completed>
-ERROR:  deadlock detected
+error in steps s2u2 s1u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -84,8 +84,8 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -94,8 +94,8 @@ step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
 step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
 step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
 step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
 step s2u2: <... completed>
+error in steps s1u2 s2u2: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
diff --git a/src/test/isolation/expected/fk-deadlock2_2.out b/src/test/isolation/expected/fk-deadlock2_2.out
deleted file mode 100644 (file)
index d61b1ed..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-Parsed test spec with 2 sessions
-
-starting permutation: s1u1 s1u2 s1c s2u1 s2u2 s2c
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1c: COMMIT;
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s2c: COMMIT;
-
-starting permutation: s1u1 s1u2 s2u1 s1c s2u2 s2c
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s1c: COMMIT;
-step s2u1: <... completed>
-ERROR:  could not serialize access due to concurrent update
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  current transaction is aborted, commands ignored until end of transaction block
-step s2c: COMMIT;
-
-starting permutation: s1u1 s2u1 s1u2 s2u2 s1c s2c
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u2: <... completed>
-ERROR:  deadlock detected
-step s1c: COMMIT;
-step s2c: COMMIT;
-
-starting permutation: s1u1 s2u1 s1u2 s2u2 s2c s1c
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u2: <... completed>
-ERROR:  deadlock detected
-step s2c: COMMIT;
-step s1c: COMMIT;
-
-starting permutation: s1u1 s2u1 s2u2 s1u2 s1c s2c
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
-step s2u2: <... completed>
-step s1c: COMMIT;
-step s2c: COMMIT;
-
-starting permutation: s1u1 s2u1 s2u2 s1u2 s2c s1c
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
-step s2u2: <... completed>
-step s2c: COMMIT;
-step s1c: COMMIT;
-
-starting permutation: s2u1 s1u1 s1u2 s2u2 s1c s2c
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u2: <... completed>
-ERROR:  deadlock detected
-step s1c: COMMIT;
-step s2c: COMMIT;
-
-starting permutation: s2u1 s1u1 s1u2 s2u2 s2c s1c
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u2: <... completed>
-ERROR:  deadlock detected
-step s2c: COMMIT;
-step s1c: COMMIT;
-
-starting permutation: s2u1 s1u1 s2u2 s1u2 s1c s2c
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
-step s2u2: <... completed>
-step s1c: COMMIT;
-step s2c: COMMIT;
-
-starting permutation: s2u1 s1u1 s2u2 s1u2 s2c s1c
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1;
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2; <waiting ...>
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  deadlock detected
-step s2u2: <... completed>
-step s2c: COMMIT;
-step s1c: COMMIT;
-
-starting permutation: s2u1 s2u2 s1u1 s2c s1u2 s1c
-step s2u1: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s2u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-step s1u1: UPDATE A SET Col1 = 1 WHERE AID = 1; <waiting ...>
-step s2c: COMMIT;
-step s1u1: <... completed>
-step s1u2: UPDATE B SET Col2 = 1 WHERE BID = 2;
-ERROR:  could not serialize access due to concurrent update
-step s1c: COMMIT;
index 69540b09346344d75da49dc733727c4fff44b51a..ca75322cc1229357a29da5a76faa6751d05ba6db 100644 (file)
@@ -14,7 +14,7 @@ step s1u: UPDATE parent SET aux = 'bar';
 step s2i: INSERT INTO child VALUES (2, 1); <waiting ...>
 step s1c: COMMIT;
 step s2i: <... completed>
-ERROR:  could not serialize access due to concurrent update
+error in steps s1c s2i: ERROR:  could not serialize access due to concurrent update
 step s2u: UPDATE parent SET aux = 'baz';
 ERROR:  current transaction is aborted, commands ignored until end of transaction block
 step s2c: COMMIT;
@@ -25,7 +25,7 @@ step s2i: INSERT INTO child VALUES (2, 1);
 step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
 step s2u: UPDATE parent SET aux = 'baz';
 step s1u: <... completed>
-ERROR:  deadlock detected
+error in steps s2u s1u: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -34,8 +34,8 @@ step s1i: INSERT INTO child VALUES (1, 1);
 step s2i: INSERT INTO child VALUES (2, 1);
 step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
 step s1u: UPDATE parent SET aux = 'bar';
-ERROR:  deadlock detected
 step s2u: <... completed>
+error in steps s1u s2u: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -45,7 +45,7 @@ step s1i: INSERT INTO child VALUES (1, 1);
 step s1u: UPDATE parent SET aux = 'bar'; <waiting ...>
 step s2u: UPDATE parent SET aux = 'baz';
 step s1u: <... completed>
-ERROR:  deadlock detected
+error in steps s2u s1u: ERROR:  deadlock detected
 step s1c: COMMIT;
 step s2c: COMMIT;
 
@@ -54,8 +54,8 @@ step s2i: INSERT INTO child VALUES (2, 1);
 step s1i: INSERT INTO child VALUES (1, 1);
 step s2u: UPDATE parent SET aux = 'baz'; <waiting ...>
 step s1u: UPDATE parent SET aux = 'bar';
-ERROR:  deadlock detected
 step s2u: <... completed>
+error in steps s1u s2u: ERROR:  deadlock detected
 step s2c: COMMIT;
 step s1c: COMMIT;
 
@@ -65,7 +65,7 @@ step s2u: UPDATE parent SET aux = 'baz';
 step s1i: INSERT INTO child VALUES (1, 1); <waiting ...>
 step s2c: COMMIT;
 step s1i: <... completed>
-ERROR:  could not serialize access due to concurrent update
+error in steps s2c s1i: ERROR:  could not serialize access due to concurrent update
 step s1u: UPDATE parent SET aux = 'bar';
 ERROR:  current transaction is aborted, commands ignored until end of transaction block
 step s1c: COMMIT;
index 01640124d0c9b44eeebd6286dcf6bc570ae6d610..023e4dc222bb8ab741a500b3d6b4ab243d86eb4a 100644 (file)
@@ -383,6 +383,50 @@ step_bsearch_cmp(const void *a, const void *b)
        return strcmp(stepname, step->name);
 }
 
+/*
+ * If a step caused an error to be reported, print it out and clear it.
+ */
+static void
+report_error_message(Step *step)
+{
+       if (step->errormsg)
+       {
+               fprintf(stdout, "%s\n", step->errormsg);
+               free(step->errormsg);
+               step->errormsg = NULL;
+       }
+}
+
+/*
+ * As above, but reports messages possibly emitted by two steps.  This is
+ * useful when we have a blocked command awakened by another one; we want to
+ * report both messages identically, for the case where we don't care which
+ * one fails due to a timeout such as deadlock timeout.
+ */
+static void
+report_two_error_messages(Step *step1, Step *step2)
+{
+       char *prefix;
+
+       prefix = malloc(strlen(step1->name) + strlen(step2->name) + 2);
+       sprintf(prefix, "%s %s", step1->name, step2->name);
+
+       if (step1->errormsg)
+       {
+               fprintf(stdout, "error in steps %s: %s\n", prefix,
+                               step1->errormsg);
+               free(step1->errormsg);
+               step1->errormsg = NULL;
+       }
+       if (step2->errormsg)
+       {
+               fprintf(stdout, "error in steps %s: %s\n", prefix,
+                               step2->errormsg);
+               free(step2->errormsg);
+               step2->errormsg = NULL;
+       }
+}
+
 /*
  * Run one permutation
  */
@@ -448,17 +492,32 @@ run_permutation(TestSpec * testspec, int nsteps, Step ** steps)
                        /* Some other step is already waiting: just block. */
                        try_complete_step(step, 0);
 
-                       /* See if this step unblocked the waiting step. */
+                       /*
+                        * See if this step unblocked the waiting step; report both error
+                        * messages together if so.
+                        */
                        if (!try_complete_step(waiting, STEP_NONBLOCK | STEP_RETRY))
+                       {
+                               report_two_error_messages(step, waiting);
                                waiting = NULL;
+                       }
+                       else
+                               report_error_message(step);
+               }
+               else
+               {
+                       if (try_complete_step(step, STEP_NONBLOCK))
+                               waiting = step;
+                       report_error_message(step);
                }
-               else if (try_complete_step(step, STEP_NONBLOCK))
-                       waiting = step;
        }
 
        /* Finish any waiting query. */
        if (waiting != NULL)
+       {
                try_complete_step(waiting, STEP_RETRY);
+               report_error_message(waiting);
+       }
 
        /* Perform per-session teardown */
        for (i = 0; i < testspec->nsessions; i++)
@@ -505,6 +564,10 @@ run_permutation(TestSpec * testspec, int nsteps, Step ** steps)
  * When calling this function on behalf of a given step for a second or later
  * time, pass the STEP_RETRY flag.  This only affects the messages printed.
  *
+ * If the connection returns an error, the message is saved in step->errormsg.
+ * Caller should call report_error_message shortly after this, to have it
+ * printed and cleared.
+ *
  * If the STEP_NONBLOCK flag was specified and the query is waiting to acquire
  * a lock, returns true.  Otherwise, returns false.
  */
@@ -579,9 +642,19 @@ try_complete_step(Step *step, int flags)
                                printResultSet(res);
                                break;
                        case PGRES_FATAL_ERROR:
+                               if (step->errormsg != NULL)
+                               {
+                                       printf("WARNING: this step had a leftover error message\n");
+                                       printf("%s\n", step->errormsg);
+                               }
                                /* Detail may contain xid values, so just show primary. */
-                               printf("%s:  %s\n", PQresultErrorField(res, PG_DIAG_SEVERITY),
-                                          PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY));
+                               step->errormsg = malloc(5 +
+                                                                               strlen(PQresultErrorField(res, PG_DIAG_SEVERITY)) + 
+                                                                               strlen(PQresultErrorField(res,
+                                                                                                                                 PG_DIAG_MESSAGE_PRIMARY)));
+                               sprintf(step->errormsg, "%s:  %s",
+                                               PQresultErrorField(res, PG_DIAG_SEVERITY),
+                                               PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY));
                                break;
                        default:
                                printf("unexpected result status: %s\n",
index 377c10c393c1829cff58c93783792d7de9f4b717..1e286df596a2067854ce687cbe3707939a915b1a 100644 (file)
@@ -31,6 +31,7 @@ struct Step
        int                     session;
        char       *name;
        char       *sql;
+       char       *errormsg;
 };
 
 typedef struct
index 47bfbc4f399eafd66687d871f3fdbbc1b4f62d7c..b4db2f0002963e81ed178c7c9bce37fdb01f8649 100644 (file)
@@ -123,6 +123,7 @@ step:
                                $$ = malloc(sizeof(Step));
                                $$->name = $2;
                                $$->sql = $3;
+                               $$->errormsg = NULL;
                        }
                ;