Skip to content

Commit 3f29b04

Browse files
bashaojingbashaojing
authored andcommitted
support oceanbase
1 parent e79d5ca commit 3f29b04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+4494
-0
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,9 @@ matrix:
144144
- sleep 5
145145
script:
146146
- CLICKHOUSE_AVAILABLE=true mvn -Dtest=ClickHouseBinaryComparisonOperationTest test
147+
- name: OceanBase
148+
jdk : openjdk8
149+
script:
150+
- OCEANBASE_AVAILABLE=true mvn -Dtest=TestOceanBaseTLP test
151+
- OCEANBASE_AVAILABLE=true mvn -Dtest=TestOceanBasePQS test
152+
- OCEANBASE_AVAILABLE=true mvn -Dtest=TestOceanBaseNoREC test

src/sqlancer/Main.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import sqlancer.postgres.PostgresProvider;
3838
import sqlancer.sqlite3.SQLite3Provider;
3939
import sqlancer.tidb.TiDBProvider;
40+
import sqlancer.oceanbase.OceanBaseProvider;
4041

4142
public final class Main {
4243

@@ -560,6 +561,7 @@ private boolean run(MainOptions options, ExecutorService execService,
560561
providers.add(new MongoDBProvider());
561562
providers.add(new CosmosProvider());
562563
providers.add(new ArangoDBProvider());
564+
providers.add(new OceanBaseProvider());
563565
return providers;
564566
}
565567

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package sqlancer.oceanbase;
2+
3+
import sqlancer.common.query.ExpectedErrors;
4+
5+
public final class OceanBaseErrors {
6+
7+
private OceanBaseErrors() {
8+
}
9+
10+
public static void addExpressionErrors(ExpectedErrors errors) {
11+
errors.add("BIGINT value is out of range"); // e.g., CAST(-('-1e500') AS SIGNED)
12+
errors.add("is not valid for CHARACTER SET");
13+
errors.add("The observer or zone is not the master");
14+
errors.add("Incorrect integer value");
15+
errors.add("Truncated incorrect DOUBLE value");
16+
errors.add("Invalid numeric");
17+
errors.add("Data truncated for argument");
18+
}
19+
public static void addInsertErrors(ExpectedErrors errors) {
20+
errors.add("Duplicate entry");
21+
errors.add("cannot be null");
22+
errors.add("doesn't have a default value");
23+
errors.add("Out of range value");
24+
errors.add("Incorrect double value");
25+
errors.add("Incorrect float value");
26+
errors.add("Incorrect int value");
27+
errors.add("Incorrect tinyint value");
28+
errors.add("Data truncation");
29+
errors.add("Bad Number");
30+
errors.add("The value specified for generated column"); // TODO: do not insert data into generated columns
31+
errors.add("incorrect utf8 value");
32+
errors.add("Data truncation: %s value is out of range in '%s'");
33+
errors.add("Incorrect smallint value");
34+
errors.add("Incorrect bigint value");
35+
errors.add("Incorrect decimal value");
36+
errors.add("error parsing regexp");
37+
errors.add("The observer or zone is not the master");
38+
errors.add("Incorrect integer value");
39+
errors.add("Truncated incorrect DOUBLE value");
40+
errors.add("Data truncated for argument");
41+
errors.add("Invalid numeric");
42+
43+
44+
if (true) {
45+
errors.add("Miss column");
46+
}
47+
}
48+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package sqlancer.oceanbase;
2+
3+
import sqlancer.IgnoreMeException;
4+
import sqlancer.oceanbase.ast.OceanBaseBinaryComparisonOperation;
5+
import sqlancer.oceanbase.ast.OceanBaseBinaryLogicalOperation;
6+
import sqlancer.oceanbase.ast.OceanBaseCastOperation;
7+
import sqlancer.oceanbase.ast.OceanBaseColumnReference;
8+
import sqlancer.oceanbase.ast.OceanBaseComputableFunction;
9+
import sqlancer.oceanbase.ast.OceanBaseConstant;
10+
import sqlancer.oceanbase.ast.OceanBaseExists;
11+
import sqlancer.oceanbase.ast.OceanBaseExpression;
12+
import sqlancer.oceanbase.ast.OceanBaseInOperation;
13+
import sqlancer.oceanbase.ast.OceanBaseOrderByTerm;
14+
import sqlancer.oceanbase.ast.OceanBaseSelect;
15+
import sqlancer.oceanbase.ast.OceanBaseStringExpression;
16+
import sqlancer.oceanbase.ast.OceanBaseTableReference;
17+
import sqlancer.oceanbase.ast.OceanBaseUnaryPostfixOperation;
18+
import sqlancer.oceanbase.ast.OceanBaseAggregate;
19+
import sqlancer.oceanbase.ast.OceanBaseColumnName;
20+
import sqlancer.oceanbase.ast.OceanBaseText;
21+
import sqlancer.oceanbase.ast.OceanBaseUnaryPrefixOperation;
22+
23+
public class OceanBaseExpectedValueVisitor implements OceanBaseVisitor {
24+
25+
private final StringBuilder sb = new StringBuilder();
26+
private int nrTabs;
27+
28+
private void print(OceanBaseExpression expr) {
29+
OceanBaseToStringVisitor v = new OceanBaseToStringVisitor();
30+
v.visit(expr);
31+
for (int i = 0; i < nrTabs; i++) {
32+
sb.append("\t");
33+
}
34+
sb.append(v.get());
35+
sb.append(" -- ");
36+
sb.append(expr.getExpectedValue());
37+
sb.append("\n");
38+
}
39+
40+
@Override
41+
public void visit(OceanBaseExpression expr) {
42+
nrTabs++;
43+
try {
44+
OceanBaseVisitor.super.visit(expr);
45+
} catch (IgnoreMeException e) {
46+
47+
}
48+
nrTabs--;
49+
}
50+
51+
@Override
52+
public void visit(OceanBaseConstant constant) {
53+
print(constant);
54+
}
55+
56+
@Override
57+
public void visit(OceanBaseColumnReference column) {
58+
print(column);
59+
}
60+
61+
@Override
62+
public void visit(OceanBaseUnaryPostfixOperation op) {
63+
print(op);
64+
visit(op.getExpression());
65+
}
66+
67+
@Override
68+
public void visit(OceanBaseComputableFunction f) {
69+
print(f);
70+
for (OceanBaseExpression expr : f.getArguments()) {
71+
visit(expr);
72+
}
73+
}
74+
75+
@Override
76+
public void visit(OceanBaseBinaryLogicalOperation op) {
77+
print(op);
78+
visit(op.getLeft());
79+
visit(op.getRight());
80+
}
81+
82+
public String get() {
83+
return sb.toString();
84+
}
85+
86+
@Override
87+
public void visit(OceanBaseSelect select) {
88+
for (OceanBaseExpression j : select.getJoinList()) {
89+
visit(j);
90+
}
91+
if (select.getWhereClause() != null) {
92+
visit(select.getWhereClause());
93+
}
94+
}
95+
96+
@Override
97+
public void visit(OceanBaseBinaryComparisonOperation op) {
98+
print(op);
99+
visit(op.getLeft());
100+
visit(op.getRight());
101+
}
102+
103+
@Override
104+
public void visit(OceanBaseCastOperation op) {
105+
print(op);
106+
visit(op.getExpr());
107+
}
108+
109+
@Override
110+
public void visit(OceanBaseInOperation op) {
111+
print(op);
112+
visit(op.getExpr());
113+
for (OceanBaseExpression right : op.getListElements()) {
114+
visit(right);
115+
}
116+
}
117+
118+
@Override
119+
public void visit(OceanBaseOrderByTerm op) {
120+
}
121+
122+
@Override
123+
public void visit(OceanBaseExists op) {
124+
print(op);
125+
visit(op.getExpr());
126+
}
127+
128+
@Override
129+
public void visit(OceanBaseStringExpression op) {
130+
print(op);
131+
}
132+
133+
@Override
134+
public void visit(OceanBaseTableReference ref) {
135+
}
136+
137+
@Override
138+
public void visit(OceanBaseAggregate aggr) {
139+
}
140+
141+
@Override
142+
public void visit(OceanBaseColumnName aggr) {
143+
}
144+
145+
@Override
146+
public void visit(OceanBaseText func) {
147+
}
148+
149+
@Override
150+
public void visit(OceanBaseUnaryPrefixOperation op){
151+
print(op);
152+
visit(op.getExpr());
153+
}
154+
155+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
package sqlancer.oceanbase;
3+
4+
import java.sql.SQLException;
5+
6+
import sqlancer.SQLGlobalState;
7+
import sqlancer.oceanbase.OceanBaseOptions.OceanBaseOracleFactory;
8+
9+
public class OceanBaseGlobalState extends SQLGlobalState<OceanBaseOptions, OceanBaseSchema> {
10+
11+
@Override
12+
protected OceanBaseSchema readSchema() throws SQLException {
13+
return OceanBaseSchema.fromConnection(getConnection(), getDatabaseName());
14+
}
15+
16+
public boolean usesPQS() {
17+
return getDbmsSpecificOptions().oracles.stream().anyMatch(o -> o == OceanBaseOracleFactory.PQS);
18+
}
19+
20+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package sqlancer.oceanbase.gen;
2+
3+
import sqlancer.IgnoreMeException;
4+
import sqlancer.Randomly;
5+
import sqlancer.oceanbase.OceanBaseSchema;
6+
import sqlancer.oceanbase.ast.OceanBaseConstant;
7+
import sqlancer.oceanbase.ast.OceanBaseSelect;
8+
import sqlancer.oceanbase.OceanBaseSchema.OceanBaseTable;
9+
import sqlancer.oceanbase.ast.OceanBaseStringExpression;
10+
11+
import java.util.List;
12+
import java.util.stream.Collectors;
13+
14+
public class OceanBaseHintGenerator {
15+
private OceanBaseSelect select;
16+
private List<OceanBaseTable> tables;
17+
private final StringBuilder sb = new StringBuilder();
18+
private Randomly r = new Randomly();
19+
20+
enum IndexHint {
21+
MERGE_JOIN,
22+
INL_JOIN,
23+
INL_HASH_JOIN,
24+
INL_MERGE_JOIN,
25+
HASH_JOIN,
26+
HASH_AGG,
27+
STREAM_AGG,
28+
USE_INDEX,
29+
IGNORE_INDEX,
30+
AGG_TO_COP,
31+
USE_INDEX_MERGE,
32+
NO_INDEX_MERGE,
33+
LEADING,
34+
PredDeduce,
35+
PDML,
36+
USE_TOJA;
37+
}
38+
39+
public OceanBaseHintGenerator(OceanBaseSelect select, List<OceanBaseTable> tables) {
40+
this.select = select;
41+
this.tables = tables;
42+
}
43+
44+
public static void generateHints(OceanBaseSelect select, List<OceanBaseTable> tables) {
45+
new OceanBaseHintGenerator(select, tables).generate();
46+
47+
}
48+
49+
private void generate() {
50+
OceanBaseTable table = Randomly.fromList(tables);
51+
switch (Randomly.fromOptions(IndexHint.values())) {
52+
case PDML:
53+
sb.append(" parallel(" + r.getInteger(0, 10) + "),enable_parallel_dml ");
54+
break;
55+
case PredDeduce:
56+
sb.append("no_pred_deduce");
57+
break;
58+
case MERGE_JOIN:
59+
tablesHint("USE_MERGE ");
60+
break;
61+
case INL_JOIN:
62+
tablesHint("USE_NL ");
63+
break;
64+
case LEADING:
65+
tablesHint(" LEADING ");
66+
break;
67+
case INL_HASH_JOIN:
68+
tablesHint("USE_HASH ");
69+
break;
70+
case INL_MERGE_JOIN:
71+
tablesHint("USE_BNL ");
72+
break;
73+
case HASH_JOIN:
74+
sb.append(" parallel(1) ");
75+
break;
76+
case HASH_AGG:
77+
sb.append("USE_HASH_AGGREGATION ");
78+
break;
79+
case STREAM_AGG:
80+
sb.append("USE_NL_MATERIALIZATION ");
81+
break;
82+
case USE_INDEX:
83+
indexesHint("INDEX_HINT ");
84+
break;
85+
case IGNORE_INDEX:
86+
sb.append("TOPK (50 50) ");
87+
break;
88+
case AGG_TO_COP:
89+
sb.append("USE_LATE_MATERIALIZATION ");
90+
break;
91+
case USE_INDEX_MERGE:
92+
sb.append("ORDERED ");
93+
break;
94+
case NO_INDEX_MERGE:
95+
tablesHint("NO_MERGE ");
96+
break;
97+
case USE_TOJA:
98+
sb.append("no_rewrite " );
99+
break;
100+
default:
101+
throw new AssertionError();
102+
}
103+
104+
select.setHint(new OceanBaseStringExpression(sb.toString(),new OceanBaseConstant.OceanBaseTextConstant(sb.toString())));
105+
}
106+
107+
private void indexesHint(String string) {
108+
sb.append(string);
109+
sb.append("(");
110+
OceanBaseTable table = Randomly.fromList(tables);
111+
List<OceanBaseSchema.OceanBaseIndex> allIndexes = table.getIndexes();
112+
if (allIndexes.isEmpty()) {
113+
throw new IgnoreMeException();
114+
}
115+
List<OceanBaseSchema.OceanBaseIndex> indexSubset = Randomly.nonEmptySubset(allIndexes);
116+
sb.append(table.getName());
117+
sb.append(", ");
118+
sb.append(indexSubset.stream().map(i -> i.getIndexName()).distinct().collect(Collectors.joining(", ")));
119+
sb.append(")");
120+
}
121+
122+
private void tablesHint(String string) {
123+
sb.append(string);
124+
sb.append("(");
125+
appendTables();
126+
sb.append(")");
127+
}
128+
129+
private void appendTables() {
130+
List<OceanBaseTable> tableSubset = Randomly.nonEmptySubset(tables);
131+
sb.append(tableSubset.stream().map(t -> t.getName()).collect(Collectors.joining(", ")));
132+
}
133+
}

0 commit comments

Comments
 (0)