77
88/**
99 * Shared skeleton for the {@link Reproducer}s of oracles that detect a bug by comparing two evaluations of a
10- * semantically-equivalent pair (e.g. {@link EETOracle}, {@link NoRECOracle}, {@link TLPWhereOracle}. All of these
11- * reduce the bug the same way: re-evaluate both sides against the reduced database and report whether they still
12- * disagree (or, when the original bug was an unexpected DBMS error, whether that same error still fires).
10+ * semantically-equivalent pair (e.g. {@link EETOracle}, {@link NoRECOracle}, {@link TLPWhereOracle}). Reduction re-runs
11+ * both sides against the reduced database and reports whether they still disagree.
1312 *
1413 * <p>
15- * This class owns that control flow (including distinguishing a still-reproducing error from an unrelated one
16- * introduced by the reduction) and the {@link #getBugInformation()} header. Subclasses supply the parts specific to
17- * their oracle: how each side is evaluated, how the two are compared, and how the failing queries are rendered in the
18- * reduced test case.
14+ * The separate case where the original bug was an unexpected DBMS error rather than a mismatch is handled by
15+ * {@link UnexpectedErrorReproducer}, so a subclass here deals only with comparing two sides and never with error
16+ * handling.
17+ *
18+ * <p>
19+ * This class owns the compare-and-report control flow and the {@link #getBugInformation()} header. Subclasses supply
20+ * how each side is evaluated, how the two are compared, and how the failing queries are rendered in the reduced test
21+ * case.
1922 *
2023 * @param <G>
2124 * the DBMS-specific global state class
2225 * @param <R>
23- * the type each side evaluates to (e.g. a result set as a list of strings, a row count, a post-image )
26+ * the type each side evaluates to (e.g. a result set as a list of strings, a row count)
2427 */
2528public abstract class AbstractComparisonReproducer <G extends SQLGlobalState <?, ?>, R > implements Reproducer <G > {
2629
2730 /**
28- * The message of the unexpected DBMS error the original bug was, or {@code null} if the original bug was a
29- * comparison mismatch rather than an error.
30- */
31- protected final String expectedErrorMessage ;
32-
33- protected AbstractComparisonReproducer (String expectedErrorMessage ) {
34- this .expectedErrorMessage = expectedErrorMessage ;
35- }
36-
37- /**
38- * Whether the recorded bug has a transformed (second) side. It does not when the bug was a DBMS error triggered by
39- * the original query alone, in which case there is no second side to evaluate or compare.
40- *
41- * @return {@code true} if {@link #evaluateTransformed} should be called
42- */
43- protected abstract boolean hasTransformedSide ();
44-
45- /**
46- * Evaluates the original side against the (reduced) database.
31+ * Evaluates the original side against the reduced database.
4732 *
4833 * @param globalState
4934 * the state whose connection points at the reduced database
@@ -56,8 +41,7 @@ protected AbstractComparisonReproducer(String expectedErrorMessage) {
5641 protected abstract R evaluateOriginal (G globalState ) throws SQLException ;
5742
5843 /**
59- * Evaluates the transformed side against the (reduced) database. Only called when {@link #hasTransformedSide()} is
60- * {@code true}.
44+ * Evaluates the transformed side against the reduced database.
6145 *
6246 * @param globalState
6347 * the state whose connection points at the reduced database
@@ -89,21 +73,9 @@ public final boolean bugStillTriggers(G globalState) {
8973 R transformed ;
9074 try {
9175 original = evaluateOriginal (globalState );
92- if (!hasTransformedSide ()) {
93- // the original bug was a DBMS error on the original query alone, which no longer occurs
94- return false ;
95- }
9676 transformed = evaluateTransformed (globalState );
97- } catch (AssertionError unexpectedError ) {
98- // a DBMS error reproduces the bug only if the original failure was the same error;
99- // other errors are artifacts of the reduction (e.g., a removed CREATE TABLE)
100- return expectedErrorMessage != null
101- && expectedErrorMessage .equals (TestOracleUtils .getUnexpectedErrorMessage (unexpectedError ));
102- } catch (SQLException | RuntimeException e ) {
103- return false ;
104- }
105- if (expectedErrorMessage != null ) {
106- // the original bug was a DBMS error, which no longer occurs
77+ } catch (AssertionError | SQLException | RuntimeException e ) {
78+ // any failure re-running the two sides means this reduced database no longer shows the mismatch
10779 return false ;
10880 }
10981 return sidesDiffer (original , transformed , globalState );
@@ -112,28 +84,21 @@ public final boolean bugStillTriggers(G globalState) {
11284 @ Override
11385 public final String getBugInformation () {
11486 StringBuilder sb = new StringBuilder ();
115- if (expectedErrorMessage != null ) {
116- sb .append ("-- On the database set up by the statements above, the following queries trigger an"
117- + " unexpected error with message: " ).append (expectedErrorMessage ).append (System .lineSeparator ());
118- } else {
119- sb .append (mismatchHeaderLine ()).append (System .lineSeparator ());
120- }
87+ sb .append (mismatchHeaderLine ()).append (System .lineSeparator ());
12188 appendQueryLines (sb );
12289 return sb .toString ();
12390 }
12491
12592 /**
126- * The header line (without trailing line separator) describing the mismatch, used when the original bug was a
127- * comparison mismatch rather than an error. For example, "-- On the database set up by the statements above, the
128- * result sets of the following queries mismatch:".
93+ * The header line (without trailing line separator) describing the mismatch. For example, "-- On the database set
94+ * up by the statements above, the result sets of the following queries mismatch:".
12995 *
13096 * @return the mismatch header line
13197 */
13298 protected abstract String mismatchHeaderLine ();
13399
134100 /**
135- * Appends the failing queries (or statements) to {@code sb}, one commented line each, so the reduced test case is
136- * self-contained. Called for both the mismatch and the error case, after the header.
101+ * Appends the failing queries to {@code sb}, one commented line each, so the reduced test case is self-contained.
137102 *
138103 * @param sb
139104 * the builder to append to
0 commit comments