Extend the EET DML oracle to UPDATE support - #1357
Conversation
| String originalStatement; | ||
| String transformedStatement; | ||
| if (Randomly.getBoolean()) { | ||
| // UPDATE also transforms the written values: each SET value expression is transformed in a scalar context. |
There was a problem hiding this comment.
I think it would be nice to have a method whose name would make the two options immediately clear. However, I assume that is not straightforward given the two return values?
There was a problem hiding this comment.
Addressed in latest push. To get around the two-return-values issue, I created a simple StatementPair class, which the methods return instances of
| } | ||
| while (result.next()) { | ||
| List<String> row = new ArrayList<>(columnCount); | ||
| for (int i = 1; i <= columnCount; i++) { |
There was a problem hiding this comment.
Just to double-check, starting from 1 here is intended?
There was a problem hiding this comment.
Yes, result.getString(i) uses JDBC ResultSet indexing, which is 1-based
| SQLQueryAdapter q = new SQLQueryAdapter(selectStatement, errors, true, | ||
| state.getOptions().canonicalizeSqlString()); | ||
| SQLancerResultSet result = null; | ||
| try { |
There was a problem hiding this comment.
We could subsequently think whether we can extract such low-level result handling logic to a more high-level API.
There was a problem hiding this comment.
Yes, this would be cleaner, I will take note of it for a future PR
| private static Map<String, List<String>> indexByRowId(List<List<String>> image) { | ||
| Map<String, List<String>> byRowId = new LinkedHashMap<>(); | ||
| for (List<String> row : image) { | ||
| byRowId.put(row.get(0), row); |
There was a problem hiding this comment.
could we have a named constant, similar to the existing ROW_ID_COLUMN? This would make it clearer what part of the code relies on this assumption.
There was a problem hiding this comment.
Addressed in latest push. Instead of using an additional named constant, I ended up designing it so that everything is derived from the existing ROW_ID_COLUMN
500c620 to
1ce0341
Compare
The EET DML oracle (
EETDMLOracle) previously transformed onlyDELETEstatements. This PR addsUPDATEto the same oracle. The key difference fromDELETEis thatUPDATEhas two kinds of transformable expression (theWHEREpredicate and eachSETvalue expression) rather than one.Comparing which rows are affected is no longer enough (two runs could change the same rows but write different values, which we would want to flag as a bug). The comparison is therefore upgraded to a full post-image (for each surviving row, its identifier together with every content column's value). This covers both
UPDATEandDELETEstatements, subsumingDELETE's previous surviving-row-set comparison. It will also, with small additions, be able to coverINSERTstatements, which will be added next.Effort has been made to make the logs for reported bugs clear, showing the post-image discrepancy of the relevant rows. Test case reduction is left to a later PR.