Skip to content

Commit b9e8469

Browse files
committed
Automatically update the schema and log statements
1 parent 2c6e765 commit b9e8469

20 files changed

+147
-313
lines changed

src/sqlancer/GlobalState.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,14 @@ public void setDatabaseName(String databaseName) {
9090

9191
protected abstract void updateSchema() throws SQLException;
9292

93+
public boolean executeStatement(Query q) throws SQLException {
94+
if (getOptions().logEachSelect()) {
95+
getLogger().writeCurrent(q.getQueryString());
96+
}
97+
boolean success = manager.execute(q);
98+
if (q.couldAffectSchema()) {
99+
updateSchema();
100+
}
101+
return success;
102+
}
93103
}

src/sqlancer/Main.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,16 @@ public void run() throws SQLException {
320320
state.setConnection(con);
321321
state.setStateLogger(logger);
322322
state.setManager(manager);
323+
if (options.logEachSelect()) {
324+
logger.writeCurrent(state.getState());
325+
}
323326
provider.generateAndTestDatabase(state);
327+
try {
328+
logger.getCurrentFileWriter().close();
329+
logger.currentFileWriter = null;
330+
} catch (IOException e) {
331+
throw new AssertionError(e);
332+
}
324333
}
325334
}
326335

src/sqlancer/QueryAdapter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,20 @@ public QueryAdapter(String query, Collection<String> expectedErrors) {
2424
this.query = query;
2525
this.expectedErrors = expectedErrors;
2626
this.couldAffectSchema = false;
27+
checkQueryString();
2728
}
2829

2930
public QueryAdapter(String query, Collection<String> expectedErrors, boolean couldAffectSchema) {
3031
this.query = query;
3132
this.expectedErrors = expectedErrors;
3233
this.couldAffectSchema = couldAffectSchema;
34+
checkQueryString();
35+
}
36+
37+
private void checkQueryString() {
38+
if (query.contains("CREATE TABLE") && !couldAffectSchema) {
39+
throw new AssertionError("CREATE TABLE statements should set couldAffectSchema to true");
40+
}
3341
}
3442

3543
@Override

src/sqlancer/StatementExecutor.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,13 @@ public void executeStatements() throws SQLException {
6464
int nrTries = 0;
6565
do {
6666
query = nextAction.getQuery(globalState);
67-
if (globalState.getOptions().logEachSelect()) {
68-
globalState.getLogger().writeCurrent(query.getQueryString());
69-
}
70-
success = globalState.getManager().execute(query);
67+
success = globalState.executeStatement(query);
7168
} while (!success && nrTries++ < globalState.getOptions().getNrStatementRetryCount());
7269
} catch (IgnoreMeException e) {
7370

7471
}
7572
if (query != null && query.couldAffectSchema()) {
73+
globalState.updateSchema();
7674
queryConsumer.notify(query);
7775
}
7876
total--;

src/sqlancer/clickhouse/ClickHouseProvider.java

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package sqlancer.clickhouse;
22

3-
import java.io.IOException;
43
import java.sql.Connection;
54
import java.sql.DriverManager;
65
import java.sql.SQLException;
@@ -13,7 +12,6 @@
1312
import sqlancer.GlobalState;
1413
import sqlancer.IgnoreMeException;
1514
import sqlancer.Main.QueryManager;
16-
import sqlancer.Main.StateLogger;
1715
import sqlancer.ProviderAdapter;
1816
import sqlancer.Query;
1917
import sqlancer.QueryAdapter;
@@ -62,10 +60,6 @@ public static class ClickHouseGlobalState extends GlobalState<ClickHouseOptions>
6260
private ClickHouseSchema schema;
6361
private ClickHouseOptions clickHouseOptions;
6462

65-
public void setSchema(ClickHouseSchema schema) {
66-
this.schema = schema;
67-
}
68-
6963
public ClickHouseSchema getSchema() {
7064
return schema;
7165
}
@@ -90,40 +84,23 @@ public String getDatabaseName() {
9084

9185
@Override
9286
protected void updateSchema() throws SQLException {
93-
setSchema(ClickHouseSchema.fromConnection(getConnection(), getDatabaseName()));
87+
this.schema = ClickHouseSchema.fromConnection(getConnection(), getDatabaseName());
9488
}
9589
}
9690

9791
@Override
9892
public void generateAndTestDatabase(ClickHouseGlobalState globalState) throws SQLException {
99-
StateLogger logger = globalState.getLogger();
10093
QueryManager manager = globalState.getManager();
101-
globalState
102-
.setSchema(ClickHouseSchema.fromConnection(globalState.getConnection(), globalState.getDatabaseName()));
10394
for (int i = 0; i < Randomly.fromOptions(1); i++) {
10495
boolean success = false;
10596
do {
10697
Query qt = new ClickHouseTableGenerator().getQuery(globalState);
107-
success = manager.execute(qt);
108-
logger.writeCurrent(globalState.getState());
109-
globalState.setSchema(
110-
ClickHouseSchema.fromConnection(globalState.getConnection(), globalState.getDatabaseName()));
111-
try {
112-
logger.getCurrentFileWriter().close();
113-
} catch (IOException e) {
114-
// TODO Auto-generated catch block
115-
e.printStackTrace();
116-
}
117-
logger.currentFileWriter = null;
98+
success = globalState.executeStatement(qt);
11899
} while (!success);
119100
}
120101

121102
StatementExecutor<ClickHouseGlobalState, Action> se = new StatementExecutor<>(globalState, Action.values(),
122103
ClickHouseProvider::mapActions, (q) -> {
123-
if (q.couldAffectSchema()) {
124-
globalState.setSchema(ClickHouseSchema.fromConnection(globalState.getConnection(),
125-
globalState.getDatabaseName()));
126-
}
127104
if (globalState.getSchema().getDatabaseTables().isEmpty()) {
128105
throw new IgnoreMeException();
129106
}
@@ -149,15 +126,6 @@ public void generateAndTestDatabase(ClickHouseGlobalState globalState) throws SQ
149126
manager.incrementSelectQueryCount();
150127
}
151128

152-
try {
153-
if (globalState.getOptions().logEachSelect()) {
154-
logger.getCurrentFileWriter().close();
155-
logger.currentFileWriter = null;
156-
}
157-
} catch (IOException e) {
158-
// TODO Auto-generated catch block
159-
e.printStackTrace();
160-
}
161129
}
162130

163131
@Override

src/sqlancer/clickhouse/gen/ClickHouseTableGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public Query getQuery(ClickHouseGlobalState globalState) {
4646
sb.append(" ORDER BY tuple()");
4747
}
4848
sb.append(";");
49-
return new QueryAdapter(sb.toString(), errors);
49+
return new QueryAdapter(sb.toString(), errors, true);
5050
}
5151

5252
private void potentiallyAppendCodec() {

src/sqlancer/cockroachdb/CockroachDBProvider.java

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package sqlancer.cockroachdb;
22

3-
import java.io.IOException;
43
import java.sql.Connection;
54
import java.sql.DriverManager;
65
import java.sql.SQLException;
@@ -15,14 +14,12 @@
1514
import sqlancer.GlobalState;
1615
import sqlancer.IgnoreMeException;
1716
import sqlancer.Main.QueryManager;
18-
import sqlancer.Main.StateLogger;
1917
import sqlancer.MainOptions;
2018
import sqlancer.ProviderAdapter;
2119
import sqlancer.Query;
2220
import sqlancer.QueryAdapter;
2321
import sqlancer.QueryProvider;
2422
import sqlancer.Randomly;
25-
import sqlancer.StateToReproduce;
2623
import sqlancer.TestOracle;
2724
import sqlancer.cockroachdb.CockroachDBProvider.CockroachDBGlobalState;
2825
import sqlancer.cockroachdb.CockroachDBSchema.CockroachDBTable;
@@ -119,32 +116,29 @@ public static class CockroachDBGlobalState extends GlobalState<CockroachDBOption
119116

120117
private CockroachDBSchema schema;
121118

122-
public void setSchema(CockroachDBSchema schema) {
123-
this.schema = schema;
124-
}
125-
126119
public CockroachDBSchema getSchema() {
120+
if (schema == null) {
121+
try {
122+
updateSchema();
123+
} catch (SQLException e) {
124+
throw new AssertionError();
125+
}
126+
}
127127
return schema;
128128
}
129129

130130
@Override
131131
protected void updateSchema() throws SQLException {
132-
setSchema(CockroachDBSchema.fromConnection(getConnection(), getDatabaseName()));
132+
this.schema = CockroachDBSchema.fromConnection(getConnection(), getDatabaseName());
133133
}
134134

135135
}
136136

137137
@Override
138138
public void generateAndTestDatabase(CockroachDBGlobalState globalState) throws SQLException {
139139
Randomly r = new Randomly();
140-
Connection con = globalState.getConnection();
141-
String databaseName = globalState.getDatabaseName();
142140
QueryManager manager = globalState.getManager();
143-
StateLogger logger = globalState.getLogger();
144-
StateToReproduce state = globalState.getState();
145141
MainOptions options = globalState.getOptions();
146-
globalState.setSchema(CockroachDBSchema.fromConnection(con, databaseName));
147-
148142
List<String> standardSettings = new ArrayList<>();
149143
standardSettings.add("--Don't send automatic bug reports\n"
150144
+ "SET CLUSTER SETTING debug.panic_on_failed_assertions = true;");
@@ -172,22 +166,12 @@ public void generateAndTestDatabase(CockroachDBGlobalState globalState) throws S
172166
do {
173167
try {
174168
Query q = CockroachDBTableGenerator.generate(globalState);
175-
success = manager.execute(q);
176-
logger.writeCurrent(state);
177-
try {
178-
logger.getCurrentFileWriter().close();
179-
} catch (IOException e) {
180-
// TODO Auto-generated catch block
181-
e.printStackTrace();
182-
}
183-
logger.currentFileWriter = null;
169+
success = globalState.executeStatement(q);
184170
} catch (IgnoreMeException e) {
185171
// continue trying
186172
}
187173
} while (!success);
188-
globalState.setSchema(CockroachDBSchema.fromConnection(con, databaseName));
189174
}
190-
logger.writeCurrent(state);
191175

192176
int[] nrRemaining = new int[Action.values().length];
193177
List<Action> actions = new ArrayList<>();
@@ -263,19 +247,13 @@ public void generateAndTestDatabase(CockroachDBGlobalState globalState) throws S
263247
int nrTries = 0;
264248
do {
265249
query = nextAction.getQuery(globalState);
266-
if (options.logEachSelect()) {
267-
logger.writeCurrent(query.getQueryString());
268-
}
269-
success = manager.execute(query);
250+
success = globalState.executeStatement(query);
270251
} while (!success && nrTries++ < 1000);
271252
} catch (IgnoreMeException e) {
272253

273254
}
274-
if (query != null && query.couldAffectSchema()) {
275-
globalState.setSchema(CockroachDBSchema.fromConnection(con, databaseName));
276-
if (globalState.getSchema().getDatabaseTables().isEmpty()) {
277-
throw new IgnoreMeException();
278-
}
255+
if (query != null && query.couldAffectSchema() && globalState.getSchema().getDatabaseTables().isEmpty()) {
256+
throw new IgnoreMeException();
279257
}
280258
total--;
281259
}
@@ -292,16 +270,6 @@ public void generateAndTestDatabase(CockroachDBGlobalState globalState) throws S
292270

293271
}
294272
}
295-
try {
296-
if (options.logEachSelect()) {
297-
logger.getCurrentFileWriter().close();
298-
logger.currentFileWriter = null;
299-
}
300-
} catch (IOException e) {
301-
// TODO Auto-generated catch block
302-
e.printStackTrace();
303-
}
304-
305273
}
306274

307275
@Override

src/sqlancer/duckdb/DuckDBProvider.java

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package sqlancer.duckdb;
22

3-
import java.io.IOException;
43
import java.sql.Connection;
54
import java.sql.DriverManager;
65
import java.sql.SQLException;
@@ -13,7 +12,6 @@
1312
import sqlancer.GlobalState;
1413
import sqlancer.IgnoreMeException;
1514
import sqlancer.Main.QueryManager;
16-
import sqlancer.Main.StateLogger;
1715
import sqlancer.ProviderAdapter;
1816
import sqlancer.Query;
1917
import sqlancer.QueryAdapter;
@@ -96,50 +94,39 @@ public static class DuckDBGlobalState extends GlobalState<DuckDBOptions> {
9694

9795
private DuckDBSchema schema;
9896

99-
public void setSchema(DuckDBSchema schema) {
100-
this.schema = schema;
101-
}
102-
10397
public DuckDBSchema getSchema() {
98+
if (schema == null) {
99+
try {
100+
updateSchema();
101+
} catch (SQLException e) {
102+
throw new AssertionError(e);
103+
}
104+
}
104105
return schema;
105106
}
106107

107108
@Override
108109
protected void updateSchema() throws SQLException {
109-
setSchema(DuckDBSchema.fromConnection(getConnection(), getDatabaseName()));
110+
this.schema = DuckDBSchema.fromConnection(getConnection(), getDatabaseName());
110111
}
111112

112113
}
113114

114115
@Override
115116
public void generateAndTestDatabase(DuckDBGlobalState globalState) throws SQLException {
116-
StateLogger logger = globalState.getLogger();
117117
QueryManager manager = globalState.getManager();
118-
globalState.setSchema(DuckDBSchema.fromConnection(globalState.getConnection(), globalState.getDatabaseName()));
119-
if (globalState.getOptions().logEachSelect()) {
120-
globalState.getLogger().writeCurrent(globalState.getState());
121-
}
122118
for (int i = 0; i < Randomly.fromOptions(1, 2); i++) {
123119
boolean success = false;
124120
do {
125121
Query qt = new DuckDBTableGenerator().getQuery(globalState);
126-
if (globalState.getOptions().logEachSelect()) {
127-
globalState.getLogger().writeCurrent(qt.getQueryString());
128-
}
129-
success = manager.execute(qt);
130-
globalState.setSchema(
131-
DuckDBSchema.fromConnection(globalState.getConnection(), globalState.getDatabaseName()));
122+
success = globalState.executeStatement(qt);
132123
} while (!success);
133124
}
134-
if (globalState.getSchema().getDatabaseTables().size() == 0) {
125+
if (globalState.getSchema().getDatabaseTables().isEmpty()) {
135126
throw new IgnoreMeException(); // TODO
136127
}
137128
StatementExecutor<DuckDBGlobalState, Action> se = new StatementExecutor<>(globalState, Action.values(),
138129
DuckDBProvider::mapActions, (q) -> {
139-
if (q.couldAffectSchema()) {
140-
globalState.setSchema(DuckDBSchema.fromConnection(globalState.getConnection(),
141-
globalState.getDatabaseName()));
142-
}
143130
if (globalState.getSchema().getDatabaseTables().isEmpty()) {
144131
throw new IgnoreMeException();
145132
}
@@ -163,15 +150,6 @@ public void generateAndTestDatabase(DuckDBGlobalState globalState) throws SQLExc
163150

164151
}
165152
}
166-
try {
167-
if (globalState.getOptions().logEachSelect()) {
168-
logger.getCurrentFileWriter().close();
169-
logger.currentFileWriter = null;
170-
}
171-
} catch (IOException e) {
172-
// TODO Auto-generated catch block
173-
e.printStackTrace();
174-
}
175153
globalState.getConnection().close();
176154
}
177155

0 commit comments

Comments
 (0)