Skip to content

Commit e99efaf

Browse files
committed
Provide a basic method skeleton in the PQS base class
1 parent 3ccb61a commit e99efaf

4 files changed

Lines changed: 74 additions & 53 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,56 @@
11
package sqlancer.common.oracle;
22

3+
import java.sql.SQLException;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
37
import sqlancer.GlobalState;
48
import sqlancer.common.query.ExpectedErrors;
9+
import sqlancer.common.query.Query;
510
import sqlancer.common.schema.AbstractRowValue;
611

712
public abstract class PivotedQuerySynthesisBase<S extends GlobalState<?, ?>, R extends AbstractRowValue<?, ?, ?>, E>
813
implements TestOracle {
914

1015
protected final ExpectedErrors errors = new ExpectedErrors();
16+
protected final List<E> rectifiedPredicates = new ArrayList<>();
1117
protected final S globalState;
1218
protected R pivotRow;
1319

1420
public PivotedQuerySynthesisBase(S globalState) {
1521
this.globalState = globalState;
1622
}
1723

24+
@Override
25+
public final void check() throws SQLException {
26+
rectifiedPredicates.clear();
27+
Query pivotRowQuery = getQueryThatContainsAtLeastOneRow();
28+
if (globalState.getOptions().logEachSelect()) {
29+
globalState.getLogger().writeCurrent(pivotRowQuery.getQueryString());
30+
}
31+
boolean isContainedIn = isContainedIn(pivotRowQuery);
32+
if (!isContainedIn) {
33+
reportMissingPivotRow(pivotRowQuery);
34+
}
35+
}
36+
37+
protected void reportMissingPivotRow(Query query) {
38+
String expectedPivotRowString = pivotRow.asStringGroupedByTables();
39+
globalState.getState().getLocalState().log(expectedPivotRowString);
40+
41+
StringBuilder sb = new StringBuilder("-- rectified predicates:\n");
42+
for (E rectifiedPredicate : rectifiedPredicates) {
43+
sb.append("--");
44+
sb.append(asString(rectifiedPredicate).replace("\n", "\n-- "));
45+
}
46+
globalState.getState().getLocalState().log(sb.toString());
47+
throw new AssertionError(query);
48+
}
49+
50+
protected abstract boolean isContainedIn(Query pivotRowQuery) throws SQLException;
51+
52+
protected abstract Query getQueryThatContainsAtLeastOneRow() throws SQLException;
53+
54+
protected abstract String asString(E expr);
55+
1856
}

src/sqlancer/mysql/oracle/MySQLPivotedQuerySynthesisOracle.java

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@
99

1010
import sqlancer.Randomly;
1111
import sqlancer.common.oracle.PivotedQuerySynthesisBase;
12+
import sqlancer.common.query.ExpectedErrors;
13+
import sqlancer.common.query.Query;
14+
import sqlancer.common.query.QueryAdapter;
1215
import sqlancer.mysql.MySQLGlobalState;
1316
import sqlancer.mysql.MySQLSchema.MySQLColumn;
1417
import sqlancer.mysql.MySQLSchema.MySQLRowValue;
1518
import sqlancer.mysql.MySQLSchema.MySQLTable;
1619
import sqlancer.mysql.MySQLSchema.MySQLTables;
1720
import sqlancer.mysql.MySQLToStringVisitor;
21+
import sqlancer.mysql.MySQLVisitor;
1822
import sqlancer.mysql.ast.MySQLColumnReference;
1923
import sqlancer.mysql.ast.MySQLConstant;
2024
import sqlancer.mysql.ast.MySQLExpression;
@@ -37,23 +41,7 @@ public MySQLPivotedQuerySynthesisOracle(MySQLGlobalState globalState) throws SQL
3741
}
3842

3943
@Override
40-
public void check() throws SQLException {
41-
String queryString = getQueryThatContainsAtLeastOneRow();
42-
43-
try {
44-
boolean isContainedIn = isContainedIn(queryString);
45-
if (!isContainedIn) {
46-
throw new AssertionError(queryString);
47-
}
48-
} catch (SQLException e) {
49-
if (!e.getMessage().contains("BIGINT value is out of range")) {
50-
throw e;
51-
}
52-
}
53-
54-
}
55-
56-
public String getQueryThatContainsAtLeastOneRow() throws SQLException {
44+
public Query getQueryThatContainsAtLeastOneRow() throws SQLException {
5745
MySQLTables randomFromTables = globalState.getSchema().getRandomTableNonEmptyTables();
5846
List<MySQLTable> tables = randomFromTables.getTables();
5947

@@ -128,7 +116,7 @@ public String getQueryThatContainsAtLeastOneRow() throws SQLException {
128116

129117
MySQLToStringVisitor visitor = new MySQLToStringVisitor();
130118
visitor.visit(selectStatement);
131-
return visitor.get();
119+
return new QueryAdapter(visitor.get(), ExpectedErrors.from("BIGINT value is out of range"));
132120
}
133121

134122
private List<MySQLExpression> generateGroupByClause(List<MySQLColumn> columns, MySQLRowValue rw) {
@@ -170,13 +158,14 @@ private MySQLExpression generateWhereClauseThatContainsRowValue(List<MySQLColumn
170158
}
171159
}
172160

173-
private boolean isContainedIn(String queryString) throws SQLException {
161+
@Override
162+
protected boolean isContainedIn(Query query) throws SQLException {
174163
Statement createStatement;
175164
createStatement = globalState.getConnection().createStatement();
176165

177166
StringBuilder sb = new StringBuilder();
178167
sb.append("SELECT * FROM ("); // ANOTHER SELECT TO USE ORDER BY without restrictions
179-
sb.append(queryString);
168+
sb.append(query.getQueryString());
180169
sb.append(") as result WHERE ");
181170
int i = 0;
182171
for (MySQLColumn c : columns) {
@@ -203,4 +192,9 @@ private boolean isContainedIn(String queryString) throws SQLException {
203192
return isContainedIn;
204193
}
205194
}
195+
196+
@Override
197+
protected String asString(MySQLExpression expr) {
198+
return MySQLVisitor.asString(expr);
199+
}
206200
}

src/sqlancer/postgres/oracle/PostgresPivotedQuerySynthesisOracle.java

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
import sqlancer.MainOptions;
1414
import sqlancer.Randomly;
1515
import sqlancer.common.oracle.PivotedQuerySynthesisBase;
16+
import sqlancer.common.query.Query;
17+
import sqlancer.common.query.QueryAdapter;
1618
import sqlancer.postgres.PostgresGlobalState;
1719
import sqlancer.postgres.PostgresSchema.PostgresColumn;
1820
import sqlancer.postgres.PostgresSchema.PostgresRowValue;
1921
import sqlancer.postgres.PostgresSchema.PostgresTables;
2022
import sqlancer.postgres.PostgresToStringVisitor;
23+
import sqlancer.postgres.PostgresVisitor;
2124
import sqlancer.postgres.ast.PostgresColumnValue;
2225
import sqlancer.postgres.ast.PostgresConstant;
2326
import sqlancer.postgres.ast.PostgresExpression;
@@ -39,22 +42,7 @@ public PostgresPivotedQuerySynthesisOracle(PostgresGlobalState globalState) thro
3942
}
4043

4144
@Override
42-
public void check() throws SQLException {
43-
String queryString = getQueryThatContainsAtLeastOneRow();
44-
globalState.getState().getLocalState().log(queryString);
45-
if (options.logEachSelect()) {
46-
logger.writeCurrent(queryString);
47-
}
48-
49-
boolean isContainedIn = isContainedIn(queryString, options, logger);
50-
if (!isContainedIn) {
51-
String assertionMessage = String.format("the query doesn't contain at least 1 row!\n-- %s;", queryString);
52-
throw new AssertionError(assertionMessage);
53-
}
54-
55-
}
56-
57-
public String getQueryThatContainsAtLeastOneRow() throws SQLException {
45+
public Query getQueryThatContainsAtLeastOneRow() throws SQLException {
5846
PostgresTables randomFromTables = globalState.getSchema().getRandomTableNonEmptyTables();
5947

6048
PostgresSelect selectStatement = new PostgresSelect();
@@ -102,7 +90,7 @@ public String getQueryThatContainsAtLeastOneRow() throws SQLException {
10290

10391
PostgresToStringVisitor visitor = new PostgresToStringVisitor();
10492
visitor.visit(selectStatement);
105-
return visitor.get();
93+
return new QueryAdapter(visitor.get());
10694
}
10795

10896
private List<PostgresExpression> generateGroupByClause(List<PostgresColumn> columns, PostgresRowValue rw) {
@@ -136,13 +124,14 @@ private PostgresExpression generateWhereClauseThatContainsRowValue(List<Postgres
136124
return PostgresExpressionGenerator.generateTrueCondition(columns, rw, globalState);
137125
}
138126

139-
private boolean isContainedIn(String queryString, MainOptions options, StateLogger logger) throws SQLException {
127+
@Override
128+
protected boolean isContainedIn(Query query) throws SQLException {
140129
Statement createStatement;
141130
createStatement = globalState.getConnection().createStatement();
142131

143132
StringBuilder sb = new StringBuilder();
144133
sb.append("SELECT * FROM ("); // ANOTHER SELECT TO USE ORDER BY without restrictions
145-
sb.append(queryString);
134+
sb.append(query.getQueryString());
146135
sb.append(") as result WHERE ");
147136
int i = 0;
148137
for (PostgresColumn c : fetchColumns) {
@@ -185,4 +174,9 @@ private boolean isContainedIn(String queryString, MainOptions options, StateLogg
185174
}
186175
}
187176

177+
@Override
178+
protected String asString(PostgresExpression expr) {
179+
return PostgresVisitor.asString(expr);
180+
}
181+
188182
}

src/sqlancer/sqlite3/oracle/SQLite3PivotedQuerySynthesisOracle.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,8 @@ public SQLite3PivotedQuerySynthesisOracle(SQLite3GlobalState globalState) throws
5252
}
5353

5454
@Override
55-
public void check() throws SQLException {
56-
Query query = getQueryThatContainsAtLeastOneRow(globalState);
57-
if (globalState.getOptions().logEachSelect()) {
58-
globalState.getLogger().writeCurrent(query.getQueryString());
59-
}
60-
boolean isContainedIn = isContainedIn(query);
61-
if (!isContainedIn) {
62-
throw new AssertionError(query);
63-
}
64-
}
65-
66-
public Query getQueryThatContainsAtLeastOneRow(SQLite3GlobalState state) throws SQLException {
67-
SQLite3Select selectStatement = getQuery(state);
55+
public Query getQueryThatContainsAtLeastOneRow() throws SQLException {
56+
SQLite3Select selectStatement = getQuery(globalState);
6857
SQLite3ToStringVisitor visitor = new SQLite3ToStringVisitor();
6958
visitor.visit(selectStatement);
7059
String queryString = visitor.get();
@@ -188,7 +177,8 @@ private SQLite3Expression generateOffset() {
188177
}
189178
}
190179

191-
private boolean isContainedIn(Query query) throws SQLException {
180+
@Override
181+
protected boolean isContainedIn(Query query) throws SQLException {
192182
Statement createStatement;
193183
createStatement = globalState.getConnection().createStatement();
194184

@@ -354,4 +344,9 @@ private enum FrameSpec {
354344
BETWEEN, UNBOUNDED_PRECEDING, CURRENT_ROW
355345
}
356346

347+
@Override
348+
protected String asString(SQLite3Expression expr) {
349+
return SQLite3Visitor.asString(expr);
350+
}
351+
357352
}

0 commit comments

Comments
 (0)