-
Notifications
You must be signed in to change notification settings - Fork 397
Expand file tree
/
Copy pathH2TableGenerator.java
More file actions
115 lines (108 loc) · 5.1 KB
/
H2TableGenerator.java
File metadata and controls
115 lines (108 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package sqlancer.h2;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import sqlancer.IgnoreMeException;
import sqlancer.Randomly;
import sqlancer.common.query.ExpectedErrors;
import sqlancer.common.query.SQLQueryAdapter;
import sqlancer.h2.H2Provider.H2GlobalState;
import sqlancer.h2.H2Schema.H2Column;
import sqlancer.h2.H2Schema.H2CompositeDataType;
import sqlancer.h2.H2Schema.H2Table;
public class H2TableGenerator {
public SQLQueryAdapter getQuery(H2GlobalState globalState) {
ExpectedErrors errors = new ExpectedErrors();
errors.add("already exists");
StringBuilder sb = new StringBuilder("CREATE TABLE ");
sb.append(globalState.getSchema().getFreeTableName());
sb.append("(");
List<String> columnNames = new ArrayList<>();
for (int i = 0; i < Randomly.fromOptions(1, 2, 3); i++) {
columnNames.add("c" + i);
}
for (int i = 0; i < columnNames.size(); i++) {
if (i != 0) {
sb.append(", ");
}
String c = columnNames.get(i);
sb.append(c);
sb.append(" ");
sb.append(H2CompositeDataType.getRandom());
boolean generated = Randomly.getBooleanWithRatherLowProbability();
if (Randomly.getBooleanWithRatherLowProbability()) {
sb.append(" NOT NULL");
}
if (Randomly.getBooleanWithRatherLowProbability() && !generated) {
sb.append(" DEFAULT ");
sb.append(H2ToStringVisitor.asString(new H2ExpressionGenerator(globalState).generateConstant()));
}
if (generated) {
sb.append(" AS (");
List<H2Column> columns = columnNames.stream().filter(cName -> !cName.contentEquals(c))
.map(c2 -> new H2Column(c2, null)).collect(Collectors.toList());
H2ExpressionGenerator gen = new H2ExpressionGenerator(globalState).setColumns(columns);
sb.append(H2ToStringVisitor.asString(gen.generateExpression()));
H2Errors.addExpressionErrors(errors);
errors.add("not found"); // generated column cycles
sb.append(')');
}
if (Randomly.getBooleanWithRatherLowProbability()) {
sb.append(" SELECTIVITY ");
sb.append(Randomly.getNotCachedInteger(0, 101));
}
if (Randomly.getBooleanWithRatherLowProbability() && !generated) {
sb.append(" UNIQUE");
}
if (Randomly.getBooleanWithRatherLowProbability()) {
sb.append(" CHECK ");
sb.append(H2ToStringVisitor.asString(new H2ExpressionGenerator(globalState)
.setColumns(columnNames.stream().map(c2 -> new H2Column(c2, null)).collect(Collectors.toList()))
.generateExpression()));
H2Errors.addExpressionErrors(errors);
}
}
if (Randomly.getBooleanWithRatherLowProbability()) {
sb.append(", PRIMARY KEY(");
sb.append(Randomly.nonEmptySubset(columnNames).stream().collect(Collectors.joining(", ")));
sb.append(")");
}
if (Randomly.getBooleanWithRatherLowProbability()) {
List<String> foreignKeyColumns = Randomly.nonEmptySubset(columnNames);
sb.append(", FOREIGN KEY(");
sb.append(foreignKeyColumns.stream().collect(Collectors.joining(", ")));
sb.append(')');
List<H2Table> foreignTableCandidates = globalState.getSchema().getDatabaseTables().stream()
.filter(t -> !t.isView()).collect(Collectors.toList());
if (foreignTableCandidates.isEmpty()) {
throw new IgnoreMeException();
}
H2Table foreignKeyTable = Randomly.fromList(foreignTableCandidates);
sb.append(" REFERENCES ");
sb.append(foreignKeyTable.getName());
sb.append('(');
if (foreignKeyTable.getColumns().size() < foreignKeyColumns.size()) {
throw new IgnoreMeException();
}
sb.append(foreignKeyTable.getRandomNonEmptyColumnSubset(foreignKeyColumns.size()).stream()
.map(c -> c.getName()).collect(Collectors.joining(", ")));
sb.append(')');
if (Randomly.getBoolean()) {
sb.append(" ON DELETE ");
addReferentialAction(sb);
}
if (Randomly.getBoolean()) {
sb.append(" ON UPDATE ");
addReferentialAction(sb);
}
errors.add("are not comparable");
errors.add(" cannot be updatable by a referential constraint with"); // generated columns
errors.add("not found"); // Constraint "PRIMARY KEY | UNIQUE (C0)" not found;
}
sb.append(")");
return new SQLQueryAdapter(sb.toString(), errors, true);
}
private void addReferentialAction(StringBuilder sb) {
sb.append(Randomly.fromOptions("CASCADE", "RESTRICT", "NO ACTION", "SET DEFAULT", "SET NULL"));
}
}