Skip to content

Commit 120bc07

Browse files
committed
Support latest versions of CockroachDB and TiDB
1 parent 8bba871 commit 120bc07

29 files changed

+316
-186
lines changed

src/sqlancer/ComparatorHelper.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,17 @@ public static List<String> getResultSetFirstColumnAsString(String queryString, E
5757
throw new IgnoreMeException();
5858
}
5959
while (result.next()) {
60-
resultSet.add(result.getString(1));
60+
String resultTemp = result.getString(1);
61+
if (resultTemp != null) {
62+
resultTemp = resultTemp.replaceAll("[\\.]0+$", "");
63+
}
64+
resultSet.add(resultTemp); // Remove the trailing zeros as many DBMS treat it as non-bugs
6165
}
6266
} catch (Exception e) {
6367
if (e instanceof IgnoreMeException) {
6468
throw e;
6569
}
66-
if (e instanceof NumberFormatException) {
67-
// https://github.com/tidb-challenge-program/bug-hunting-issue/issues/57
68-
throw new IgnoreMeException();
69-
}
70+
7071
if (e.getMessage() == null) {
7172
throw new AssertionError(queryString, e);
7273
}

src/sqlancer/Randomly.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,17 @@ public static <T> List<T> extractNrRandomColumns(List<T> columns, int nr) {
159159

160160
public static int smallNumber() {
161161
// no need to cache for small numbers
162-
return (int) (Math.abs(getThreadRandom().get().nextGaussian()) * 2);
162+
return (int) (Math.abs(getThreadRandom().get().nextGaussian())) * 2;
163163
}
164164

165165
public static boolean getBoolean() {
166166
return getThreadRandom().get().nextBoolean();
167167
}
168168

169+
public static double getPercentage() {
170+
return getThreadRandom().get().nextDouble();
171+
}
172+
169173
private static ThreadLocal<Random> getThreadRandom() {
170174
if (THREAD_RANDOM.get() == null) {
171175
// a static method has been called, before Randomly was instantiated

src/sqlancer/SQLProviderAdapter.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@ protected void checkViewsAreValid(G globalState) {
2525
for (AbstractTable<?, ?, ?> view : views) {
2626
SQLQueryAdapter q = new SQLQueryAdapter("SELECT 1 FROM " + view.getName() + " LIMIT 1");
2727
try {
28-
q.execute(globalState);
28+
if (!q.execute(globalState)) {
29+
throw new AssertionError();
30+
}
2931
} catch (Throwable t) {
30-
throw new IgnoreMeException();
32+
try {
33+
globalState.executeStatement(new SQLQueryAdapter("DROP VIEW " + view.getName(), true));
34+
} catch (Throwable t2) {
35+
throw new IgnoreMeException();
36+
}
3137
}
3238
}
3339
}

src/sqlancer/cockroachdb/CockroachDBBugs.java

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,52 @@
33
public final class CockroachDBBugs {
44

55
// https://github.com/cockroachdb/cockroach/issues/46915
6-
public static boolean bug46915 = true;
6+
public static boolean bug46915;
77

88
// https://github.com/cockroachdb/cockroach/issues/45703
9-
public static boolean bug45703 = true;
9+
public static boolean bug45703;
1010

1111
// https://github.com/cockroachdb/cockroach/issues/44757
12-
public static boolean bug44757 = true;
12+
public static boolean bug44757;
13+
14+
// https://github.com/cockroachdb/cockroach/issues/83792
15+
public static boolean bug83792 = true;
16+
17+
// https://github.com/cockroachdb/cockroach/issues/83874
18+
public static boolean bug83874 = true;
19+
20+
// https://github.com/cockroachdb/cockroach/issues/83973
21+
public static boolean bug83973 = true;
22+
23+
// https://github.com/cockroachdb/cockroach/issues/83976
24+
public static boolean bug83976 = true;
25+
26+
// https://github.com/cockroachdb/cockroach/issues/84154
27+
public static boolean bug84154 = true;
28+
29+
// https://github.com/cockroachdb/cockroach/issues/85356
30+
public static boolean bug85356 = true;
31+
32+
// https://github.com/cockroachdb/cockroach/issues/85371
33+
public static boolean bug85371 = true;
34+
35+
// https://github.com/cockroachdb/cockroach/issues/85389
36+
public static boolean bug85389 = true;
37+
38+
// https://github.com/cockroachdb/cockroach/issues/85390
39+
public static boolean bug85390 = true;
40+
41+
// https://github.com/cockroachdb/cockroach/issues/85393
42+
public static boolean bug85393 = true;
43+
44+
// https://github.com/cockroachdb/cockroach/issues/85394
45+
public static boolean bug85394 = true;
46+
47+
// https://github.com/cockroachdb/cockroach/issues/85441
48+
public static boolean bug85441 = true;
49+
50+
// https://github.com/cockroachdb/cockroach/issues/85499
51+
public static boolean bug85499 = true;
1352

1453
private CockroachDBBugs() {
1554
}

src/sqlancer/cockroachdb/CockroachDBErrors.java

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ public static void addExpressionErrors(ExpectedErrors errors) {
3333
errors.add("expected -9223372036854775809 to be of type int, found type decimal");
3434
errors.add("to be of type int4, found type decimal");
3535

36-
errors.add("as type bool: invalid bool value");
37-
errors.add("as type int: strconv.ParseInt");
38-
errors.add("as type float: strconv.ParseFloat: parsing");
36+
errors.add("as type bool");
37+
errors.add("as type int");
38+
errors.add("as type float");
3939

4040
errors.add("is not in select list");
4141
errors.add("non-integer constant in ORDER BY");
@@ -68,9 +68,7 @@ public static void addExpressionErrors(ExpectedErrors errors) {
6868
errors.add("unsupported comparison operator: <string> = <bytes>");
6969
errors.add("unsupported comparison operator: <string> <= <bytes>");
7070
errors.add("to be of type string, found type bytes");
71-
errors.add("unknown signature: left(string, int) (desired <bytes>)");
7271
errors.add("unknown signature: bit_length(collatedstring");
73-
errors.add("ERROR: unknown signature: left(collatedstring");
7472
errors.add("unsupported comparison operator: <string> !~ <collatedstring{");
7573
errors.add("unsupported comparison operator: <collatedstring");
7674
errors.add(" unsupported comparison operator: <string> NOT LIKE <collatedstring{");
@@ -109,11 +107,10 @@ public static void addExpressionErrors(ExpectedErrors errors) {
109107
errors.add("as int4, found type: decimal");
110108
errors.add("to be of type int2, found type decimal");
111109
errors.add("to be of type int, found type decimal"); // arithmetic overflows
112-
errors.add("unknown signature: left(string, decimal)");
113-
errors.add("unknown signature: left(bytes, decimal) (desired <bytes>)");
110+
errors.add("unknown signature: left");
114111
errors.add("numeric constant out of int64 range");
115-
errors.add("unknown signature: overlay(string, string, decimal)");
116-
errors.add("unknown signature: substring(string, int, decimal)");
112+
errors.add("unknown signature: overlay");
113+
errors.add("unknown signature: substring");
117114
errors.add("unsupported binary operator: <unknown> + <decimal> (desired <int>)");
118115
errors.add("unsupported comparison operator");
119116
errors.add("unknown signature: chr(decimal) (desired <string>)");
@@ -122,25 +119,20 @@ public static void addExpressionErrors(ExpectedErrors errors) {
122119
errors.add("incompatible value type: expected rowid to be of type decimal, found type int");
123120
errors.add("unknown signature: to_english(decimal)");
124121
errors.add("unknown signature: chr(decimal)");
125-
errors.add(" unknown signature: left(string, int2) (desired <bytes>)");
126-
errors.add("unknown signature: split_part(string, string, decimal) (desired <string>)");
127-
errors.add(" unknown signature: substring(string, ");
122+
errors.add("unknown signature: split_part");
128123
errors.add("division by zero");
129124
errors.add("as int, found type: decimal");
130125
errors.add("value type decimal doesn't match type int2 ");
131126
errors.add("has type decimal");
132127
errors.add("to be of type decimal, found type int");
133128
errors.add("value type decimal doesn't match type int");
134-
errors.add("unknown signature: substring(string, decimal, int)");
135129
errors.add("unsupported binary operator: <int> / <int> (desired <int4>)");
136130
errors.add("(desired <int>)");
137131
errors.add("(desired <int2>)");
138132
errors.add("(desired <int4>)");
139133
errors.add("found type: decimal");
140134
errors.add("(desired <decimal>)");
141135
errors.add("unknown signature: to_hex(decimal)");
142-
errors.add("unknown signature: split_part(string, string, decimal)");
143-
errors.add("unknown signature: left(bytes, decimal)");
144136
errors.add("division undefined");
145137
errors.add("decimal out of range");
146138
errors.add("unknown signature: xor_agg(decimal)");
@@ -155,14 +147,45 @@ public static void addExpressionErrors(ExpectedErrors errors) {
155147
errors.add("could not parse JSON: unable to decode JSON: EOF");
156148
errors.add("could not parse JSON: unable to decode JSON: unexpected EOF");
157149
errors.add("can't order by column type jsonb");
150+
errors.add("odd length hex string");
158151

159152
// TODO: better control what is generated in a view
160153
errors.add("aggregate functions are not allowed in GROUP BY");
161154
errors.add(" must appear in the GROUP BY clause or be used in an aggregate function");
162155

163-
if (CockroachDBBugs.bug44757) {
156+
if (CockroachDBBugs.bug83874) {
164157
errors.add("no builtin aggregate");
165158
}
159+
if (CockroachDBBugs.bug83792) {
160+
errors.add("comparison overload not found");
161+
}
162+
if (CockroachDBBugs.bug83973) {
163+
errors.add("invalid memory address");
164+
}
165+
if (CockroachDBBugs.bug83976) {
166+
errors.add("cannot execute distinct on no columns");
167+
}
168+
if (CockroachDBBugs.bug85356) {
169+
errors.add("inconsistent Case return types");
170+
}
171+
if (CockroachDBBugs.bug85371) {
172+
errors.add("index out of range");
173+
}
174+
if (CockroachDBBugs.bug85389) {
175+
errors.add("no volatility for cast decimal");
176+
}
177+
if (CockroachDBBugs.bug85390) {
178+
errors.add("lookup for ComparisonExpr");
179+
}
180+
if (CockroachDBBugs.bug85393) {
181+
errors.add("no output column equivalent to");
182+
}
183+
if (CockroachDBBugs.bug85441) {
184+
errors.add("cannot cast jsonb numeric to type bool");
185+
}
186+
if (CockroachDBBugs.bug85499) {
187+
errors.add("estimated row count must be non-zero");
188+
}
166189

167190
errors.add("unable to vectorize execution plan"); // SET vectorize=experimental_always;
168191
errors.add(" mismatched physical types at index"); // SET vectorize=experimental_always;
@@ -223,7 +246,7 @@ private static void addArrayErrors(ExpectedErrors errors) {
223246
errors.add("unimplemented: nested arrays not supported"); // e.g., casting a string {{1}} to an array
224247
errors.add("malformed array");
225248

226-
errors.add("https://github.com/cockroachdb/cockroach/issues/35707"); // arrays don't support ORDER BY
249+
// errors.add("https://github.com/cockroachdb/cockroach/issues/35707"); // arrays don't support ORDER BY
227250

228251
errors.add("as bytes[], found type: varbit[]");
229252
errors.add("to be of type decimal[], found type float[]");
@@ -234,7 +257,7 @@ private static void addArrayErrors(ExpectedErrors errors) {
234257

235258
private static void addIntervalTypeErrors(ExpectedErrors errors) {
236259
errors.add("overflow during Encode");
237-
errors.add("as type interval");
260+
errors.add("type interval");
238261
}
239262

240263
private static void addJoinTypes(ExpectedErrors errors) {
@@ -269,7 +292,6 @@ private static void addFunctionErrors(ExpectedErrors errors) {
269292
// functions
270293
errors.add("abs of min integer value (-9223372036854775808) not defined"); // ABS
271294
errors.add("the input string must not be empty"); // ASCII
272-
errors.add("unknown signature: substring(string, decimal)"); // overflow
273295
errors.add("overlay(): non-positive substring length not allowed"); // overlay
274296
errors.add("non-positive substring length not allowed"); // overlay
275297
errors.add("lpad(): requested length too large"); // lpad

src/sqlancer/cockroachdb/CockroachDBOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public TestOracle create(CockroachDBGlobalState globalState) throws SQLException
9797
public boolean testHashIndexes = true;
9898

9999
@Parameter(names = { "--test-temp-tables" }, description = "Test TEMPORARY tables")
100-
public boolean testTempTables = true;
100+
public boolean testTempTables; // default: false https://github.com/cockroachdb/cockroach/issues/85388
101101

102102
@Parameter(names = {
103103
"--increased-vectorization" }, description = "Generate VECTORIZE=on with a higher probability (which found a number of bugs in the past)")

src/sqlancer/cockroachdb/CockroachDBSchema.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,14 @@ public CockroachDBTable(String tableName, List<CockroachDBColumn> columns, List<
274274

275275
}
276276

277+
public int getIndexCount() {
278+
int count = 0;
279+
for (CockroachDBTable table : getDatabaseTables()) {
280+
count += table.getIndexes().size();
281+
}
282+
return count;
283+
}
284+
277285
public static CockroachDBSchema fromConnection(SQLConnection con, String databaseName) throws SQLException {
278286
List<CockroachDBTable> databaseTables = new ArrayList<>();
279287
List<String> tableNames = getTableNames(con);
@@ -285,6 +293,10 @@ public static CockroachDBSchema fromConnection(SQLConnection con, String databas
285293
for (CockroachDBColumn c : databaseColumns) {
286294
c.setTable(t);
287295
}
296+
// To avoid some situations that columns can not be got.
297+
if (databaseColumns.isEmpty()) {
298+
continue;
299+
}
288300
databaseTables.add(t);
289301

290302
}
@@ -334,6 +346,11 @@ private static List<CockroachDBColumn> getTableColumns(SQLConnection con, String
334346
isNullable);
335347
columns.add(c);
336348
}
349+
} catch (SQLException e) {
350+
if (CockroachDBBugs.bug85394 && e.getMessage().contains("incompatible type annotation for ARRAY")) {
351+
return columns;
352+
}
353+
throw e;
337354
}
338355
}
339356
return columns;

src/sqlancer/cockroachdb/ast/CockroachDBConstant.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,20 +230,22 @@ public static CockroachDBExpression createBitConstantWithSize(int size) {
230230
}
231231

232232
public static CockroachDBExpression createTimestampConstant(long integer) {
233-
return new CockroachDBTimeRelatedConstant("TIMESTAMP", integer, "yyyy-MM-dd");
233+
return new CockroachDBTimeRelatedConstant("TIMESTAMP", integer, "yyyy-MM-dd'T'HH:mm:ss");
234234
}
235235

236236
public static CockroachDBExpression createTimeConstant(long integer) {
237-
return new CockroachDBTimeRelatedConstant("TIME", integer, "HH:mm:ss");
237+
return new CockroachDBTimeRelatedConstant("TIME", integer, "yyyy-MM-dd'T'HH:mm:ss");
238238
}
239239

240240
public static CockroachDBExpression createTimetz(long integer) {
241-
return new CockroachDBTimeRelatedConstant("TIMETZ", integer, "HH:mm:ss"); // TODO: support the complete format
241+
return new CockroachDBTimeRelatedConstant("TIMETZ", integer, "yyyy-MM-dd'T'HH:mm:ss"); // TODO: support the
242+
// complete format
242243
}
243244

244245
public static CockroachDBExpression createTimestamptzConstant(long integer) {
245-
return new CockroachDBTimeRelatedConstant("TIMESTAMPTZ", integer, "HH:mm:ss"); // TODO: support the complete
246-
// format
246+
return new CockroachDBTimeRelatedConstant("TIMESTAMPTZ", integer, "yyyy-MM-dd'T'HH:mm:ss"); // TODO: support the
247+
// complete
248+
// format
247249
}
248250

249251
public static CockroachDBExpression createIntervalConstant(long year, long month, long day, long hour, long minute,

src/sqlancer/cockroachdb/gen/CockroachDBCreateStatisticsGenerator.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@ public static SQLQueryAdapter create(CockroachDBGlobalState globalState) {
2222
sb.append(" FROM ");
2323
sb.append(randomTable.getName());
2424

25-
return new SQLQueryAdapter(sb.toString(),
26-
ExpectedErrors.from("current transaction is aborted, commands ignored until end of transaction block",
27-
"ERROR: unable to encode table key: *tree.DArray" /*
28-
* https://github.com/cockroachdb/cockroach/
29-
* issues/46964
30-
*/, "overflow during Encode"));
25+
return new SQLQueryAdapter(sb.toString(), ExpectedErrors.from("overflow during Encode")); // https://github.com/cockroachdb/cockroach/issues/84078
3126
}
3227

3328
}

src/sqlancer/cockroachdb/gen/CockroachDBIndexGenerator.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.List;
44

55
import sqlancer.Randomly;
6+
import sqlancer.cockroachdb.CockroachDBBugs;
67
import sqlancer.cockroachdb.CockroachDBProvider.CockroachDBGlobalState;
78
import sqlancer.cockroachdb.CockroachDBSchema.CockroachDBColumn;
89
import sqlancer.cockroachdb.CockroachDBSchema.CockroachDBTable;
@@ -30,6 +31,10 @@ public void buildStatement() {
3031
errors.add("the following columns are not indexable due to their type"); // array types are not indexable
3132
errors.add("cannot determine type of empty array. Consider annotating with the desired type");
3233
errors.add("incompatible IF expression"); // TODO: investigate; seems to be a bug
34+
if (CockroachDBBugs.bug84154) {
35+
errors.add("overflow during Encode");
36+
errors.add("of type interval");
37+
}
3338
CockroachDBTable table = globalState.getSchema().getRandomTable(t -> !t.isView());
3439
sb.append("CREATE ");
3540
if (Randomly.getBoolean()) {
@@ -43,15 +48,19 @@ public void buildStatement() {
4348
&& Randomly.getBooleanWithSmallProbability();
4449
if (hashSharded) {
4550
sb.append(" USING HASH WITH BUCKET_COUNT=");
46-
sb.append(Randomly.getNotCachedInteger(2, Short.MAX_VALUE));
51+
sb.append(Randomly.getNotCachedInteger(2, 2048));
4752
errors.add("null value in column");
4853
errors.add("cannot create a sharded index on a computed column");
4954
}
5055
if (Randomly.getBoolean()) {
51-
sb.append(" ");
52-
sb.append(Randomly.fromOptions("STORING", "COVERING"));
53-
sb.append(" ");
54-
addColumns(sb, table.getRandomNonEmptyColumnSubset(), false);
56+
List<CockroachDBColumn> columns2 = table.getRandomNonEmptyColumnSubset();
57+
columns2.removeAll(columns);
58+
if (!columns2.isEmpty()) {
59+
sb.append(" ");
60+
sb.append(Randomly.fromOptions("STORING", "COVERING"));
61+
sb.append(" ");
62+
addColumns(sb, columns2, false);
63+
}
5564
}
5665
}
5766

0 commit comments

Comments
 (0)