Skip to content

Commit f852f8c

Browse files
Add support for Presto - common classes (#884)
To implement support for Presto some changes in common classes are required. ## Changes in common classes: 1. class sqlancer.MainOptions - added global parameters : * canonicalizeString (boolean) - presto doesn't support JDBC queries with ";" at the end of statement * compareResultsContent (boolean) - comparing content of VARBINARY columns fails 2. class sqlancer.ComparatorHelper - compare result based on parameter ``` boolean compare = state.getOptions().compareResultsContent(); if (compare && !firstHashSet.equals(secondHashSet)) { ``` 3. sqlancer.common.query.SQLancerResultSet - added method: ``` public String getType(int i) throws SQLException { return rs.getMetaData().getColumnTypeName(i); } ``` 4. sqlancer.common.query.SQLQueryAdapter : added constructor ``` public SQLQueryAdapter(String query, ExpectedErrors expectedErrors, boolean couldAffectSchema, boolean canonicalizeString) { ```
1 parent 706ac16 commit f852f8c

File tree

5 files changed

+54
-7
lines changed

5 files changed

+54
-7
lines changed

src/sqlancer/ComparatorHelper.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public static List<String> getResultSetFirstColumnAsString(String queryString, E
4848
e.printStackTrace();
4949
}
5050
}
51-
SQLQueryAdapter q = new SQLQueryAdapter(queryString, errors);
51+
boolean canonicalizeString = state.getOptions().canonicalizeSqlString();
52+
SQLQueryAdapter q = new SQLQueryAdapter(queryString, errors, true, canonicalizeString);
5253
List<String> resultSet = new ArrayList<>();
5354
SQLancerResultSet result = null;
5455
try {
@@ -106,7 +107,8 @@ public static void assumeResultSetsAreEqual(List<String> resultSet, List<String>
106107
Set<String> firstHashSet = new HashSet<>(resultSet);
107108
Set<String> secondHashSet = new HashSet<>(secondResultSet);
108109

109-
if (!firstHashSet.equals(secondHashSet)) {
110+
boolean validateResultSizeOnly = state.getOptions().validateResultSizeOnly();
111+
if (!validateResultSizeOnly && !firstHashSet.equals(secondHashSet)) {
110112
Set<String> firstResultSetMisses = new HashSet<>(firstHashSet);
111113
firstResultSetMisses.removeAll(secondHashSet);
112114
Set<String> secondResultSetMisses = new HashSet<>(secondHashSet);

src/sqlancer/MainOptions.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ public class MainOptions {
141141
@Parameter(names = "--ast-reducer-max-time", description = "EXPERIMENTAL Maximum time duration (secs) the statement reducer will do")
142142
private long maxStatementReduceTime = NO_REDUCE_LIMIT; // NOPMD
143143

144+
@Parameter(names = "--validate-result-size-only", description = "Should validate result size only and skip comparing content of the result set ", arity = 1)
145+
private boolean validateResultSizeOnly = false; // NOPMD
146+
147+
@Parameter(names = "--canonicalize-sql-strings", description = "Should canonicalize query string (add ';' at the end", arity = 1)
148+
private boolean canonicalizeSqlString = true; // NOPMD
149+
144150
public int getMaxExpressionDepth() {
145151
return maxExpressionDepth;
146152
}
@@ -322,4 +328,12 @@ public long getMaxASTReduceTime() {
322328
return maxASTReduceTime;
323329
}
324330

331+
public boolean validateResultSizeOnly() {
332+
return validateResultSizeOnly;
333+
}
334+
335+
public boolean canonicalizeSqlString() {
336+
return canonicalizeSqlString;
337+
}
338+
325339
}

src/sqlancer/common/query/SQLQueryAdapter.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,16 @@ private static boolean guessAffectSchemaFromQuery(String query) {
3232
}
3333

3434
public SQLQueryAdapter(String query, ExpectedErrors expectedErrors, boolean couldAffectSchema) {
35-
this.query = canonicalizeString(query);
35+
this(query, expectedErrors, couldAffectSchema, true);
36+
}
37+
38+
public SQLQueryAdapter(String query, ExpectedErrors expectedErrors, boolean couldAffectSchema,
39+
boolean canonicalizeString) {
40+
if (canonicalizeString) {
41+
this.query = canonicalizeString(query);
42+
} else {
43+
this.query = query;
44+
}
3645
this.expectedErrors = expectedErrors;
3746
this.couldAffectSchema = couldAffectSchema;
3847
checkQueryString();

src/sqlancer/common/query/SQLancerResultSet.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public long getLong(int i) throws SQLException {
4646
return rs.getLong(i);
4747
}
4848

49+
public String getType(int i) throws SQLException {
50+
return rs.getMetaData().getColumnTypeName(i);
51+
}
52+
4953
public void registerEpilogue(Runnable runnableEpilogue) {
5054
this.runnableEpilogue = runnableEpilogue;
5155
}

test/sqlancer/TestComparatorHelper.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,37 @@
22

33
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
44

5+
import java.sql.SQLException;
56
import java.util.Arrays;
67
import java.util.List;
78

89
import org.junit.jupiter.api.Test;
910

11+
import sqlancer.h2.H2Options;
12+
import sqlancer.h2.H2Schema;
13+
1014
public class TestComparatorHelper {
1115
// TODO: Implement tests for the other ComparatorHelper methods
1216

17+
// TODO: create test state that not depends on specific database
18+
final SQLGlobalState<H2Options, H2Schema> state = new SQLGlobalState<H2Options, H2Schema>() {
19+
20+
@Override
21+
protected H2Schema readSchema() throws SQLException {
22+
return H2Schema.fromConnection(getConnection(), getDatabaseName());
23+
}
24+
25+
@Override
26+
public MainOptions getOptions() {
27+
return new MainOptions();
28+
}
29+
};
30+
1331
@Test
1432
public void testAssumeResultSetsAreEqualWithEqualSets() {
1533
List<String> r1 = Arrays.asList("a", "b", "c");
1634
List<String> r2 = Arrays.asList("a", "b", "c");
17-
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), null);
35+
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), state);
1836

1937
}
2038

@@ -26,7 +44,7 @@ public void testAssumeResultSetsAreEqualWithUnequalLengthSets() {
2644
// line occurs before AssertionError is thrown, but it's good enough as an indicator that one of the Exceptions
2745
// is raised
2846
assertThrowsExactly(NullPointerException.class, () -> {
29-
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), null);
47+
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), state);
3048
});
3149
}
3250

@@ -38,15 +56,15 @@ public void testAssumeResultSetsAreEqualWithUnequalValueSets() {
3856
// line occurs before AssertionError is thrown, but it's good enough as an indicator that one of the Exceptions
3957
// is raised
4058
assertThrowsExactly(NullPointerException.class, () -> {
41-
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), null);
59+
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), state);
4260
});
4361
}
4462

4563
@Test
4664
public void testAssumeResultSetsAreEqualWithCanonicalizationRule() {
4765
List<String> r1 = Arrays.asList("a", "b", "c");
4866
List<String> r2 = Arrays.asList("a", "b", "d");
49-
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), null, (String s) -> {
67+
ComparatorHelper.assumeResultSetsAreEqual(r1, r2, "", Arrays.asList(""), state, (String s) -> {
5068
return s.equals("d") ? "c" : s;
5169
});
5270
}

0 commit comments

Comments
 (0)