Skip to content

Commit 8a5ea5d

Browse files
authored
Merge pull request sqlancer#1275 from Mohab-Sobhy/feat/mariadb-add-delete-generator
Add DeleteGenerator for MariaDB
2 parents a4c67cd + 35105ec commit 8a5ea5d

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

src/sqlancer/mariadb/MariaDBProvider.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import sqlancer.common.DBMSCommon;
2020
import sqlancer.common.query.SQLQueryAdapter;
2121
import sqlancer.mariadb.MariaDBProvider.MariaDBGlobalState;
22+
import sqlancer.mariadb.gen.MariaDBDeleteGenerator;
2223
import sqlancer.mariadb.gen.MariaDBIndexGenerator;
2324
import sqlancer.mariadb.gen.MariaDBInsertGenerator;
2425
import sqlancer.mariadb.gen.MariaDBSetGenerator;
@@ -47,6 +48,7 @@ enum Action {
4748
SET, //
4849
TRUNCATE, //
4950
UPDATE, //
51+
DELETE,
5052
}
5153

5254
@Override
@@ -77,6 +79,9 @@ public void generateDatabase(MariaDBGlobalState globalState) throws Exception {
7779
case CREATE_INDEX:
7880
nrPerformed = globalState.getRandomly().getInteger(0, 2);
7981
break;
82+
case DELETE:
83+
nrPerformed = globalState.getRandomly().getInteger(0, 2);
84+
break;
8085
case SET:
8186
nrPerformed = 20;
8287
break;
@@ -140,6 +145,9 @@ public void generateDatabase(MariaDBGlobalState globalState) throws Exception {
140145
case SET:
141146
query = MariaDBSetGenerator.set(globalState.getRandomly(), options);
142147
break;
148+
case DELETE:
149+
query = MariaDBDeleteGenerator.delete(globalState.getSchema(), globalState.getRandomly());
150+
break;
143151
default:
144152
throw new AssertionError(nextAction);
145153
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package sqlancer.mariadb.gen;
2+
3+
import java.util.Collections;
4+
5+
import sqlancer.Randomly;
6+
import sqlancer.common.query.ExpectedErrors;
7+
import sqlancer.common.query.SQLQueryAdapter;
8+
import sqlancer.common.schema.AbstractTables;
9+
import sqlancer.mariadb.MariaDBSchema;
10+
import sqlancer.mariadb.MariaDBSchema.MariaDBColumn;
11+
import sqlancer.mariadb.MariaDBSchema.MariaDBTable;
12+
import sqlancer.mariadb.ast.MariaDBVisitor;
13+
14+
public final class MariaDBDeleteGenerator {
15+
16+
private MariaDBDeleteGenerator() {
17+
}
18+
19+
public static SQLQueryAdapter delete(MariaDBSchema schema, Randomly r) {
20+
MariaDBTable table = schema.getRandomTable();
21+
22+
MariaDBExpressionGenerator expressionGenerator = new MariaDBExpressionGenerator(r);
23+
24+
AbstractTables<MariaDBTable, MariaDBColumn> tablesAndColumns = new AbstractTables<>(
25+
Collections.singletonList(table));
26+
expressionGenerator.setTablesAndColumns(tablesAndColumns);
27+
28+
ExpectedErrors errors = new ExpectedErrors();
29+
30+
errors.add("foreign key constraint fails");
31+
errors.add("cannot delete or update a parent row");
32+
errors.add("Data truncated");
33+
errors.add("Division by 0");
34+
errors.add("Incorrect value");
35+
36+
StringBuilder sb = new StringBuilder("DELETE");
37+
38+
if (Randomly.getBooleanWithRatherLowProbability()) {
39+
sb.append(" LOW_PRIORITY");
40+
}
41+
if (Randomly.getBooleanWithRatherLowProbability()) {
42+
sb.append(" QUICK");
43+
}
44+
if (Randomly.getBooleanWithRatherLowProbability()) {
45+
sb.append(" IGNORE");
46+
}
47+
48+
sb.append(" FROM ");
49+
sb.append(table.getName());
50+
51+
if (Randomly.getBoolean()) {
52+
sb.append(" WHERE ");
53+
if (Randomly.getBooleanWithRatherLowProbability()) {
54+
sb.append(MariaDBVisitor.asString(MariaDBExpressionGenerator.getRandomConstant(r)));
55+
} else {
56+
sb.append(MariaDBVisitor.asString(expressionGenerator.getRandomExpression()));
57+
}
58+
}
59+
60+
// ORDER BY + LIMIT
61+
if (Randomly.getBooleanWithRatherLowProbability() && !table.getColumns().isEmpty()) {
62+
sb.append(" ORDER BY ");
63+
sb.append(Randomly.fromList(table.getColumns()).getName());
64+
if (Randomly.getBoolean()) {
65+
sb.append(Randomly.getBoolean() ? " ASC" : " DESC");
66+
}
67+
}
68+
69+
if (Randomly.getBooleanWithRatherLowProbability()) {
70+
sb.append(" LIMIT ");
71+
sb.append(Randomly.getNotCachedInteger(1, 10));
72+
}
73+
74+
// RETURNING clause (MariaDB >= 10.5)
75+
if (Randomly.getBooleanWithRatherLowProbability()) {
76+
sb.append(" RETURNING ");
77+
if (Randomly.getBooleanWithRatherLowProbability()) {
78+
sb.append(MariaDBVisitor.asString(MariaDBExpressionGenerator.getRandomConstant(r)));
79+
} else {
80+
sb.append(MariaDBVisitor.asString(expressionGenerator.getRandomExpression()));
81+
}
82+
}
83+
84+
String query = sb.toString();
85+
if (query.contains("RLIKE") || query.contains("REGEXP")) {
86+
errors.add("Regex error");
87+
errors.add("quantifier does not follow a repeatable item");
88+
errors.add("Got error");
89+
}
90+
91+
return new SQLQueryAdapter(query, errors);
92+
}
93+
}

0 commit comments

Comments
 (0)