forked from sqlancer/sqlancer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDorisTableGenerator.java
More file actions
112 lines (100 loc) · 5.2 KB
/
DorisTableGenerator.java
File metadata and controls
112 lines (100 loc) · 5.2 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
package sqlancer.doris.gen;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
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.doris.DorisErrors;
import sqlancer.doris.DorisProvider.DorisGlobalState;
import sqlancer.doris.DorisSchema;
import sqlancer.doris.DorisSchema.DorisColumn;
import sqlancer.doris.DorisSchema.DorisCompositeDataType;
import sqlancer.doris.visitor.DorisToStringVisitor;
public class DorisTableGenerator {
// private final ExpectedErrors errors = new ExpectedErrors();
public static SQLQueryAdapter createRandomTableStatement(DorisGlobalState globalState) throws SQLException {
if (globalState.getSchema().getDatabaseTables().size() > globalState.getDbmsSpecificOptions().maxNumTables) {
throw new IgnoreMeException();
}
return new DorisTableGenerator().getQuery(globalState);
}
public SQLQueryAdapter getQuery(DorisGlobalState globalState) {
ExpectedErrors errors = new ExpectedErrors();
StringBuilder sb = new StringBuilder();
String tableName = globalState.getSchema().getFreeTableName();
DorisSchema.DorisTableDataModel dataModel = DorisSchema.DorisTableDataModel.getRandom();
sb.append("CREATE TABLE ");
sb.append(tableName);
sb.append("(");
List<DorisColumn> columns = getNewColumns(globalState);
Collections.sort(columns);
if (columns.isEmpty() || !columns.get(0).isKey()) {
return null; // ensure table has at least one key column
}
sb.append(columns.stream().map(DorisColumn::toString).collect(Collectors.joining(", ")));
sb.append(")");
List<DorisColumn> keysColumn = columns.stream().filter(DorisColumn::isKey).collect(Collectors.toList());
if (globalState.getDbmsSpecificOptions().testDataModel && Randomly.getBoolean() && !keysColumn.isEmpty()) {
sb.append(" " + dataModel).append(" KEY(");
sb.append(keysColumn.stream().map(c -> c.getName()).collect(Collectors.joining(", ")));
sb.append(")");
}
sb.append(generateDistributionStr(globalState, dataModel, keysColumn));
sb.append(" PROPERTIES (\"replication_num\" = \"1\")"); // now only consider this one parameter
DorisErrors.addExpressionErrors(errors);
return new SQLQueryAdapter(sb.toString(), errors, true);
}
public static String generateDistributionStr(DorisGlobalState globalState,
DorisSchema.DorisTableDataModel dataModel, List<DorisColumn> keysColumn) {
// DISTRIBUTED BY HASH (k1[,k2 ...]) [BUCKETS num]
// DISTRIBUTED BY RANDOM [BUCKETS num]
StringBuilder sb = new StringBuilder();
sb.append(" DISTRIBUTED BY");
if (dataModel == DorisSchema.DorisTableDataModel.UNIQUE || Randomly.getBoolean()) {
sb.append(" HASH (");
sb.append(Randomly.nonEmptySubset(keysColumn).stream().map(DorisColumn::getName)
.collect(Collectors.joining(", ")));
sb.append(")");
} else {
sb.append(" RANDOM");
}
if (Randomly.getBoolean()) {
sb.append(" BUCKETS ").append(globalState.getRandomly().getInteger(1, 32));
}
return sb.toString();
}
private static List<DorisColumn> getNewColumns(DorisGlobalState globalState) {
List<DorisColumn> columns = new ArrayList<>();
for (int i = 0; i < Randomly.smallNumber() + 1; i++) {
String columnName = String.format("c%d", i);
DorisCompositeDataType columnType = DorisCompositeDataType.getRandomWithoutNull();
columnType.initColumnArgs(); // set decimalAndVarchar
boolean iskey = columnType.canBeKey() && Randomly.getBoolean();
boolean isNullable = Randomly.getBoolean();
if (!globalState.getDbmsSpecificOptions().testNotNullConstraints) {
isNullable = true;
}
// boolean isHllOrBitmap = (columnType.getPrimitiveDataType() == DorisSchema.DorisDataType.HLL)
// || (columnType.getPrimitiveDataType() == DorisSchema.DorisDataType.BITMAP);
boolean isHllOrBitmap = false;
DorisSchema.DorisColumnAggrType aggrType = DorisSchema.DorisColumnAggrType.NULL;
if (globalState.getDbmsSpecificOptions().testColumnAggr && (isHllOrBitmap || !iskey)) {
aggrType = DorisSchema.DorisColumnAggrType.getRandom(columnType);
}
boolean hasDefaultValue = globalState.getDbmsSpecificOptions().testDefaultValues && Randomly.getBoolean()
&& !isHllOrBitmap;
String defaultValue = "";
if (hasDefaultValue) {
defaultValue = DorisToStringVisitor.asString(new DorisNewExpressionGenerator(globalState)
.generateConstant(columnType.getPrimitiveDataType(), isNullable));
}
columns.add(new DorisColumn(columnName, columnType, iskey, isNullable, aggrType, hasDefaultValue,
defaultValue));
}
return columns;
}
}