Skip to content

Commit 23a960e

Browse files
committed
fix: fix readSchema Exception and error insert value
1 parent 54bdd81 commit 23a960e

File tree

9 files changed

+91
-84
lines changed

9 files changed

+91
-84
lines changed

src/sqlancer/GlobalState.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import sqlancer.common.schema.AbstractSchema;
66
import sqlancer.common.schema.AbstractTable;
77

8+
import java.sql.SQLException;
9+
810
public abstract class GlobalState<O extends DBMSSpecificOptions<?>, S extends AbstractSchema<?, ?>, C extends SQLancerDBConnection> {
911

1012
protected C databaseConnection;
@@ -142,7 +144,12 @@ protected void setSchema(S schema) {
142144
}
143145

144146
public void updateSchema() throws Exception {
145-
setSchema(readSchema());
147+
try{
148+
setSchema(readSchema());
149+
} catch (SQLException sqlException) {
150+
System.out.println(String.format("%s readSchema SQLException",databaseName));
151+
sqlException.printStackTrace();
152+
}
146153
for (AbstractTable<?, ?, ?> table : schema.getDatabaseTables()) {
147154
table.recomputeCount();
148155
}

src/sqlancer/Main.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -440,12 +440,6 @@ private String formatInteger(long intValue) {
440440
try {
441441
executorFactory.getDBMSExecutor(options.getDatabasePrefix() + "connectiontest", new Randomly())
442442
.testConnection();
443-
//临时测试databend connection TODO
444-
if(executorFactory.provider.getDBMSName() == "databend"){
445-
System.out.println("Databend连接成功!");
446-
return 0; //正常退出
447-
}
448-
//-----------------
449443
} catch (Exception e) {
450444
System.err.println(
451445
"SQLancer failed creating a test database, indicating that SQLancer might have failed connecting to the DBMS. In order to change the username, password, host and port, you can use the --username, --password, --host and --port options.\n\n");

src/sqlancer/databend/DatabendProvider.java

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ public DatabendProvider() {
2424
public enum Action implements AbstractAction<DatabendGlobalState> {
2525

2626
INSERT(DatabendInsertGenerator::getQuery), //
27-
CREATE_INDEX(DatabendIndexGenerator::getQuery), //
28-
VACUUM((g) -> new SQLQueryAdapter("VACUUM;")), //
29-
ANALYZE((g) -> new SQLQueryAdapter("ANALYZE;")), //
30-
DELETE(DatabendDeleteGenerator::generate), //
31-
UPDATE(DatabendUpdateGenerator::getQuery), //
27+
//TODO 等待databend实现update && delete
28+
// DELETE(DatabendDeleteGenerator::generate), //
29+
// UPDATE(DatabendUpdateGenerator::getQuery), //
3230
CREATE_VIEW(DatabendViewGenerator::generate), //
3331
EXPLAIN((g) -> {
3432
ExpectedErrors errors = new ExpectedErrors();
@@ -57,19 +55,13 @@ private static int mapActions(DatabendGlobalState globalState, Action a) {
5755
switch (a) {
5856
case INSERT:
5957
return r.getInteger(0, globalState.getOptions().getMaxNumberInserts());
60-
case CREATE_INDEX:
61-
if (!globalState.getDbmsSpecificOptions().testIndexes) {
62-
return 0;
63-
}
64-
// fall through
65-
case UPDATE:
66-
return r.getInteger(0, globalState.getDbmsSpecificOptions().maxNumUpdates + 1);
67-
case VACUUM: // seems to be ignored
68-
case ANALYZE: // seems to be ignored
6958
case EXPLAIN:
7059
return r.getInteger(0, 2);
71-
case DELETE:
72-
return r.getInteger(0, globalState.getDbmsSpecificOptions().maxNumDeletes + 1);
60+
//TODO 等待databend实现update && delete
61+
// case UPDATE:
62+
// return r.getInteger(0, globalState.getDbmsSpecificOptions().maxNumUpdates + 1);
63+
// case DELETE:
64+
// return r.getInteger(0, globalState.getDbmsSpecificOptions().maxNumDeletes + 1);
7365
case CREATE_VIEW:
7466
return r.getInteger(0, globalState.getDbmsSpecificOptions().maxNumViews + 1);
7567
default:
@@ -136,29 +128,27 @@ public SQLConnection createDatabase(DatabendGlobalState globalState) throws SQLE
136128
port = DatabendOptions.DEFAULT_PORT;
137129
}
138130
String databaseName = globalState.getDatabaseName();
139-
//记录日志和执行语句处放一起或许比较合适? TODO
140-
globalState.getState().logStatement("DROP DATABASE IF EXISTS " + databaseName);
141-
globalState.getState().logStatement("CREATE DATABASE " + databaseName);
142-
globalState.getState().logStatement("USE " + databaseName);
143-
//--------------------------------------------
144131
String url = String.format("jdbc:mysql://%s:%d?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true",
145132
host, port);
146133
Connection con = DriverManager.getConnection(url, username, password);
147134
try (Statement s = con.createStatement()) {
148135
s.execute("DROP DATABASE IF EXISTS " + databaseName);
136+
globalState.getState().logStatement("DROP DATABASE IF EXISTS " + databaseName);
149137
}
150138
try (Statement s = con.createStatement()) {
151139
s.execute("CREATE DATABASE " + databaseName);
140+
globalState.getState().logStatement("CREATE DATABASE " + databaseName);
152141
}
153142
try (Statement s = con.createStatement()) {
154143
s.execute("USE " + databaseName);
144+
globalState.getState().logStatement("USE " + databaseName);
155145
}
156146
return new SQLConnection(con);
157147
}
158148

159149
@Override
160150
public String getDBMSName() {
161-
return "databend";
151+
return "databend"; //用于DatabendOptions
162152
}
163153

164154
}

src/sqlancer/databend/DatabendSchema.java

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ public static DatabendDataType getRandomWithoutNull() {
2929
return dt;
3030
}
3131

32+
public static DatabendDataType getRandomWithoutNullAndVarchar() {
33+
DatabendDataType dt;
34+
do {
35+
dt = Randomly.fromOptions(values());
36+
} while (dt == DatabendDataType.NULL || dt == DatabendDataType.VARCHAR);
37+
return dt;
38+
}
39+
3240
}
3341

3442
public static class DatabendCompositeDataType {
@@ -82,24 +90,24 @@ public String toString() {
8290
case INT:
8391
switch (size) {
8492
case 8:
85-
return Randomly.fromOptions("BIGINT", "INT8");
93+
return Randomly.fromOptions("BIGINT", "INT64");
8694
case 4:
87-
return Randomly.fromOptions("INTEGER", "INT", "INT4", "SIGNED");
95+
return Randomly.fromOptions("INT", "INT32");
8896
case 2:
89-
return Randomly.fromOptions("SMALLINT", "INT2");
97+
return Randomly.fromOptions("SMALLINT", "INT16");
9098
case 1:
91-
return Randomly.fromOptions("TINYINT", "INT1");
99+
return Randomly.fromOptions("TINYINT", "INT8");
92100
default:
93101
throw new AssertionError(size);
94102
}
95103
case VARCHAR:
96-
return "VARCHAR";
104+
return Randomly.fromOptions("VARCHAR");
97105
case FLOAT:
98106
switch (size) {
99107
case 8:
100108
return Randomly.fromOptions("DOUBLE");
101109
case 4:
102-
return Randomly.fromOptions("REAL", "FLOAT4");
110+
return Randomly.fromOptions("FLOAT");
103111
default:
104112
throw new AssertionError(size);
105113
}
@@ -162,7 +170,7 @@ private static DatabendCompositeDataType getColumnType(String typeString) {
162170
return new DatabendCompositeDataType(DatabendDataType.FLOAT, 8);
163171
}
164172
switch (typeString) {
165-
case "INTEGER":
173+
case "INT":
166174
primitiveType = DatabendDataType.INT;
167175
size = 4;
168176
break;
@@ -171,7 +179,6 @@ private static DatabendCompositeDataType getColumnType(String typeString) {
171179
size = 2;
172180
break;
173181
case "BIGINT":
174-
case "HUGEINT": // TODO: 16-bit int
175182
primitiveType = DatabendDataType.INT;
176183
size = 8;
177184
break;
@@ -222,12 +229,12 @@ public DatabendTable(String tableName, List<DatabendColumn> columns, boolean isV
222229

223230
public static DatabendSchema fromConnection(SQLConnection con, String databaseName) throws SQLException {
224231
List<DatabendTable> databaseTables = new ArrayList<>();
225-
List<String> tableNames = getTableNames(con);
232+
List<String> tableNames = getTableNames(con,databaseName);
226233
for (String tableName : tableNames) {
227234
if (DBMSCommon.matchesIndexName(tableName)) {
228235
continue; // TODO: unexpected?
229236
}
230-
List<DatabendColumn> databaseColumns = getTableColumns(con, tableName);
237+
List<DatabendColumn> databaseColumns = getTableColumns(con, tableName,databaseName);
231238
boolean isView = tableName.startsWith("v");
232239
DatabendTable t = new DatabendTable(tableName, databaseColumns, isView);
233240
for (DatabendColumn c : databaseColumns) {
@@ -239,37 +246,52 @@ public static DatabendSchema fromConnection(SQLConnection con, String databaseNa
239246
return new DatabendSchema(databaseTables);
240247
}
241248

242-
private static List<String> getTableNames(SQLConnection con) throws SQLException {
243-
List<String> tableNames = new ArrayList<>();
249+
private static List<String> getTableNames(SQLConnection con, String databaseName) throws SQLException {
250+
List<String> tableNames = null;
251+
tableNames = new ArrayList<>();
252+
//SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE table_schema != 'system' and table_schema != 'INFORMATION_SCHEMA' and table_type='BASE TABLE'
253+
//"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = '%s' and table_type='BASE TABLE' ",databaseName
254+
final String sqlStatement = String.format(
255+
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = '%s' and table_type='BASE TABLE' ",databaseName);
244256
try (Statement s = con.createStatement()) {
245-
try (ResultSet rs = s.executeQuery("SELECT * FROM sqlite_master WHERE type='table' or type='view'")) {
246-
while (rs.next()) {
247-
tableNames.add(rs.getString("name"));
257+
try (ResultSet rs = s.executeQuery(sqlStatement)) {
258+
try{ //没有catch的话rs.next()会报SQLException:Not a navigable ResultSet
259+
while (rs.next()) {
260+
tableNames.add(rs.getString("table_name"));
261+
}
262+
} catch (Exception e){
263+
// e.printStackTrace();
264+
System.out.println("TableNames->SQLException:Not a navigable ResultSet");
248265
}
249266
}
250267
}
251268
return tableNames;
252269
}
253270

254-
private static List<DatabendColumn> getTableColumns(SQLConnection con, String tableName) throws SQLException {
271+
private static List<DatabendColumn> getTableColumns(SQLConnection con, String tableName, String databaseName) throws SQLException {
255272
List<DatabendColumn> columns = new ArrayList<>();
256273
try (Statement s = con.createStatement()) {
257-
try (ResultSet rs = s.executeQuery(String.format("SELECT * FROM pragma_table_info('%s');", tableName))) {
258-
while (rs.next()) {
259-
String columnName = rs.getString("name");
260-
String dataType = rs.getString("type");
261-
boolean isNullable = rs.getString("notnull").contentEquals("false");
262-
boolean isPrimaryKey = rs.getString("pk").contains("true");
263-
DatabendColumn c = new DatabendColumn(columnName, getColumnType(dataType), isPrimaryKey, isNullable);
264-
columns.add(c);
274+
try (ResultSet rs = s.executeQuery(String.format(
275+
"SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = '%s' and table_name ='%s'",
276+
databaseName,tableName))) {
277+
try{ //没有catch的话rs.next()会报SQLException:Not a navigable ResultSet
278+
while (rs.next()) {
279+
String columnName = rs.getString("column_name");
280+
String dataType = rs.getString("data_type");
281+
boolean isNullable = rs.getBoolean("is_nullable");
282+
// boolean isPrimaryKey = rs.getString("pk").contains("true");
283+
boolean isPrimaryKey = false; //没找到主键元数据
284+
DatabendColumn c = new DatabendColumn(columnName, getColumnType(dataType), isPrimaryKey, isNullable);
285+
columns.add(c);
286+
}
287+
} catch (Exception e) {
288+
System.out.println("TableColumns->SQLException:Not a navigable ResultSet");
265289
}
266290
}
267291
}
268292
if (columns.stream().noneMatch(c -> c.isPrimaryKey())) {
269-
// https://github.com/cwida/Databend/issues/589
270-
// https://github.com/cwida/Databend/issues/588
271293
// TODO: implement an option to enable/disable rowids
272-
columns.add(new DatabendColumn("rowid", new DatabendCompositeDataType(DatabendDataType.INT, 4), false, false));
294+
// columns.add(new DatabendColumn("rowid", new DatabendCompositeDataType(DatabendDataType.INT, 4), false, false));
273295
}
274296
return columns;
275297
}

src/sqlancer/databend/ast/DatabendConstant.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@ public String toString() {
5757
} else if (value == Double.NEGATIVE_INFINITY) {
5858
return "'-Inf'";
5959
}
60-
return String.valueOf(value);
60+
61+
62+
// DecimalFormat doubleFormat = new DecimalFormat();
63+
// doubleFormat.setMaximumFractionDigits(2); //小数点后2位
64+
// System.out.println(String.valueOf(doubleFormat.format(value)));
65+
//TODO value先返回0.3来取消指数形式表达,等待Databend支持指数形式表达
66+
return String.valueOf(0.3);
6167
}
6268

6369
}

src/sqlancer/databend/gen/DatabendExpressionGenerator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ public Node<DatabendExpression> generateConstant() {
123123
if (Randomly.getBooleanWithSmallProbability()) {
124124
return DatabendConstant.createNullConstant();
125125
}
126-
DatabendDataType type = DatabendDataType.getRandomWithoutNull();
126+
// DatabendDataType type = DatabendDataType.getRandomWithoutNull();
127+
//TODO 先跳过varchar等待databend对其更好的支持,或自己改写case VARCHAR的代码
128+
DatabendDataType type = DatabendDataType.getRandomWithoutNullAndVarchar();
127129
switch (type) {
128130
case INT:
129131
if (!globalState.getDbmsSpecificOptions().testIntConstants) {

src/sqlancer/databend/gen/DatabendInsertGenerator.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,16 @@ private SQLQueryAdapter generate() {
4242

4343
@Override
4444
protected void insertValue(DatabendColumn tiDBColumn) {
45-
// TODO: select a more meaningful value
46-
if (Randomly.getBooleanWithRatherLowProbability()) {
47-
sb.append("DEFAULT");
48-
} else {
49-
sb.append(DatabendToStringVisitor.asString(new DatabendExpressionGenerator(globalState).generateConstant()));
50-
}
45+
// TODO: 等Databend实现NULL 和 DEFAULT ,暂时注入普通的value
46+
// if (Randomly.getBooleanWithRatherLowProbability()) {
47+
// sb.append("DEFAULT");
48+
// } else {
49+
// sb.append(DatabendToStringVisitor.asString(new DatabendExpressionGenerator(globalState).generateConstant()));
50+
// }
51+
52+
String value = DatabendToStringVisitor.asString(new DatabendExpressionGenerator(globalState).generateConstant());
53+
sb.append(value);
54+
5155
}
5256

5357
}

test/sqlancer/databend/TestDatabendConnection.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.mongodb.annotations.ThreadSafe;
44
import org.junit.jupiter.api.Test;
55
import sqlancer.Main;
6+
import sqlancer.Randomly;
67
import sqlancer.dbms.TestConfig;
78

89
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -13,7 +14,7 @@ void testConnection(){
1314
assertEquals(0,
1415
Main.executeMain(new String[] { "--random-seed", "0", "--timeout-seconds", TestConfig.SECONDS,
1516
"--num-threads", "1", "--num-queries", TestConfig.NUM_QUERIES, "--database-prefix","databend",
16-
"--host","192.168.81.133","--port","3307","--username","user1"
17+
"--random-string-generation", String.valueOf(Randomly.StringGenerationStrategy.NUMERIC),"--host","192.168.81.134","--port","3307","--username","user1"
1718
,"databend","--oracle","NoREC"}));
1819
}
1920
}

test/sqlancer/dbms/TestDatabend.java

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)