From 42af31923a4930add4c55634fb7d1519b9fbbe36 Mon Sep 17 00:00:00 2001 From: malwaregarry Date: Fri, 23 Aug 2024 09:30:09 +0800 Subject: [PATCH] [StoneDB] Remove implementation --- .github/workflows/main.yml | 29 -- src/check_names.py | 1 - src/sqlancer/Main.java | 2 - src/sqlancer/stonedb/StoneDBBugs.java | 51 -- src/sqlancer/stonedb/StoneDBErrors.java | 63 --- src/sqlancer/stonedb/StoneDBOptions.java | 99 ---- src/sqlancer/stonedb/StoneDBProvider.java | 157 ------- src/sqlancer/stonedb/StoneDBSchema.java | 441 ------------------ .../stonedb/StoneDBToStringVisitor.java | 101 ---- .../stonedb/ast/StoneDBAdvancedFunction.java | 34 -- .../stonedb/ast/StoneDBAggregate.java | 34 -- src/sqlancer/stonedb/ast/StoneDBConstant.java | 211 --------- .../stonedb/ast/StoneDBExpression.java | 4 - src/sqlancer/stonedb/ast/StoneDBJoin.java | 126 ----- src/sqlancer/stonedb/ast/StoneDBSelect.java | 17 - .../gen/StoneDBExpressionGenerator.java | 340 -------------- .../gen/StoneDBIndexCreateGenerator.java | 121 ----- .../gen/StoneDBIndexDropGenerator.java | 47 -- .../gen/StoneDBTableAlterGenerator.java | 141 ------ .../gen/StoneDBTableCreateGenerator.java | 266 ----------- .../gen/StoneDBTableDeleteGenerator.java | 70 --- .../gen/StoneDBTableInsertGenerator.java | 142 ------ .../gen/StoneDBTableUpdateGenerator.java | 71 --- .../gen/StoneDBViewCreateGenerator.java | 78 ---- .../oracle/StoneDBAggregateOracle.java | 170 ------- .../stonedb/oracle/StoneDBFuzzOracle.java | 67 --- .../stonedb/oracle/StoneDBNoRECOracle.java | 134 ------ .../oracle/StoneDBQueryPartitioningBase.java | 71 --- ...toneDBQueryPartitioningDistinctTester.java | 42 -- ...StoneDBQueryPartitioningGroupByTester.java | 50 -- .../StoneDBQueryPartitioningHavingTester.java | 47 -- .../StoneDBQueryPartitioningWhereTester.java | 42 -- test/sqlancer/dbms/TestStoneDBFuzz.java | 21 - test/sqlancer/dbms/TestStoneDBNoRec.java | 22 - test/sqlancer/dbms/TestStoneDBTLP.java | 21 - 35 files changed, 3333 deletions(-) delete mode 100644 src/sqlancer/stonedb/StoneDBBugs.java delete mode 100644 src/sqlancer/stonedb/StoneDBErrors.java delete mode 100644 src/sqlancer/stonedb/StoneDBOptions.java delete mode 100644 src/sqlancer/stonedb/StoneDBProvider.java delete mode 100644 src/sqlancer/stonedb/StoneDBSchema.java delete mode 100644 src/sqlancer/stonedb/StoneDBToStringVisitor.java delete mode 100644 src/sqlancer/stonedb/ast/StoneDBAdvancedFunction.java delete mode 100644 src/sqlancer/stonedb/ast/StoneDBAggregate.java delete mode 100644 src/sqlancer/stonedb/ast/StoneDBConstant.java delete mode 100644 src/sqlancer/stonedb/ast/StoneDBExpression.java delete mode 100644 src/sqlancer/stonedb/ast/StoneDBJoin.java delete mode 100644 src/sqlancer/stonedb/ast/StoneDBSelect.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBExpressionGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBIndexCreateGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBIndexDropGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBTableAlterGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBTableCreateGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBTableDeleteGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBTableInsertGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBTableUpdateGenerator.java delete mode 100644 src/sqlancer/stonedb/gen/StoneDBViewCreateGenerator.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBAggregateOracle.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBFuzzOracle.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBNoRECOracle.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningBase.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningDistinctTester.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningGroupByTester.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningHavingTester.java delete mode 100644 src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningWhereTester.java delete mode 100644 test/sqlancer/dbms/TestStoneDBFuzz.java delete mode 100644 test/sqlancer/dbms/TestStoneDBNoRec.java delete mode 100644 test/sqlancer/dbms/TestStoneDBTLP.java diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 56bca0594..68b02c443 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -451,35 +451,6 @@ jobs: run: | mvn -Dtest=TestSQLiteQPG test - stonedb: - name: DBMS Tests (StoneDB) - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set up StoneDB - run: | - docker run -p 3306:3306 -itd -e MYSQL_ROOT_PASSWORD='123456' stoneatom/stonedb - ContainerID=$(docker ps --filter ancestor=stoneatom/stonedb --format "{{.ID}}") - docker exec $ContainerID bash - sleep 60s - docker exec $ContainerID sed -i "s/tianmu_insert_delayed=1/tianmu_insert_delayed=0/" /opt/stonedb57/install/my.cnf - docker exec $ContainerID /opt/stonedb57/install/bin/mysql -uroot -p123456 -e "CREATE USER 'sqlancer'@'%' IDENTIFIED WITH mysql_native_password BY 'sqlancer'; GRANT ALL PRIVILEGES ON *.* TO 'sqlancer'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;" - sleep 60s - - name: Set up JDK 11 - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: '11' - cache: 'maven' - - name: Build - run: mvn -B package -DskipTests=true - - name: StoneDB Tests - run: | - STONEDB_AVAILABLE=true mvn test -Dtest=TestStoneDBFuzz - tidb: name: DBMS Tests (TiDB) runs-on: ubuntu-latest diff --git a/src/check_names.py b/src/check_names.py index 41694e060..f2ab346c6 100644 --- a/src/check_names.py +++ b/src/check_names.py @@ -53,5 +53,4 @@ def verify_all_dbs(name_to_files: dict[str:List[str]]): name_to_files["TiDB"] = get_java_files(os.path.join(cwd, "src", "sqlancer", "tidb")) name_to_files["Y"] = get_java_files(os.path.join(cwd, "src", "sqlancer", "yugabyte")) # has both YCQL and YSQL prefixes name_to_files["Doris"] = get_java_files(os.path.join(cwd, "src", "sqlancer", "doris")) - name_to_files["StoneDB"] = get_java_files(os.path.join(cwd, "src", "sqlancer", "stonedb")) verify_all_dbs(name_to_files) diff --git a/src/sqlancer/Main.java b/src/sqlancer/Main.java index 1cbc02645..5ffc3e94c 100644 --- a/src/sqlancer/Main.java +++ b/src/sqlancer/Main.java @@ -43,7 +43,6 @@ import sqlancer.presto.PrestoProvider; import sqlancer.questdb.QuestDBProvider; import sqlancer.sqlite3.SQLite3Provider; -import sqlancer.stonedb.StoneDBProvider; import sqlancer.tidb.TiDBProvider; import sqlancer.timescaledb.TimescaleDBProvider; import sqlancer.yugabyte.ycql.YCQLProvider; @@ -746,7 +745,6 @@ private static void checkForIssue799(List> providers) providers.add(new PostgresProvider()); providers.add(new QuestDBProvider()); providers.add(new SQLite3Provider()); - providers.add(new StoneDBProvider()); providers.add(new TiDBProvider()); providers.add(new TimescaleDBProvider()); providers.add(new YCQLProvider()); diff --git a/src/sqlancer/stonedb/StoneDBBugs.java b/src/sqlancer/stonedb/StoneDBBugs.java deleted file mode 100644 index 4864c56e5..000000000 --- a/src/sqlancer/stonedb/StoneDBBugs.java +++ /dev/null @@ -1,51 +0,0 @@ -package sqlancer.stonedb; - -public final class StoneDBBugs { - // https://github.com/stoneatom/stonedb/issues/1933 - public static boolean bug1933 = true; - // https://github.com/stoneatom/stonedb/issues/1942 - public static boolean bug1942 = true; - // https://github.com/stoneatom/stonedb/issues/1953 - public static boolean bug1953 = true; - // https://github.com/stoneatom/stonedb/issues/1945 - public static boolean bug1945 = true; - // CREATE TABLE t0(c0 INT); - // INSERT IGNORE INTO t0(c0) VALUE (DEFAULT); - // SELECT t0.c0 FROM t0 WHERE 0.4; -- expect 1 but got 0 - public static boolean bugNotReported1 = true; - // DELETE statements will result into crash, for example - // DELETE LOW_PRIORITY FROM t0; - // DELETE QUICK IGNORE FROM t0 WHERE -1370759901; - public static boolean bugNotReported2 = true; - // CREATE TABLE t0(c0 INT) ; - // INSERT INTO t0(c0) VALUES (DEFAULT); - // SELECT t0.c0 FROM t0 WHERE (('OC')>=(((t0.c0) IS NULL))); -- expected empty set but got 1 row - public static boolean bugNotReported3 = true; - // CREATE TABLE t0(c0 CHAR PRIMARY KEY); - // INSERT IGNORE INTO t0(c0) VALUE (DEFAULT); - // SELECT t0.c0 FROM t0 WHERE (t0.c0 BETWEEN (0) AND t0.c0); -- 1 - public static boolean bugNotReported4 = true; - // CREATE TABLE t0(c0 INT); - // INSERT INTO t0(c0) VALUE (DEFAULT); - // SELECT * FROM t0 WHERE (('00')>((('')AND(t0.c0)))); -- expected empty set but got 1 row - public static boolean bugNotReported5 = true; - // CREATE TABLE t0(c0 INT) ; - // INSERT INTO t0(c0) VALUE (100); - // SELECT * FROM t0 WHERE (('Xg')>(t0.c0)); -- expected empty set but got 1 row - // SELECT (('Xg')>(t0.c0)) FROM t0; - public static boolean bugNotReported6 = true; - // CREATE TABLE t0(c0 VARCHAR(1000)); - // INSERT INTO t0(c0) VALUE ('GX9vartD'); - // INSERT INTO t0(c0) VALUE ('16'); - // SELECT t0.c0 FROM t0 WHERE t0.c0; -- expected 1 row but got 2 rows - public static boolean bugNotReported7 = true; - // CREATE TABLE t0(c0 INT) ; - // SELECT * FROM t0 WHERE ((t0.c0)XOR((t0.c0))); - // ERROR 6 (HY000): The query includes syntax that is not supported by the storage engine. Either restructure the - // query with supported syntax, or enable the MySQL core::Query Path in config file to execute the query with - // reduced performance. - public static boolean bugNotReportedXOR = true; - - private StoneDBBugs() { - } -} diff --git a/src/sqlancer/stonedb/StoneDBErrors.java b/src/sqlancer/stonedb/StoneDBErrors.java deleted file mode 100644 index d8b0fd416..000000000 --- a/src/sqlancer/stonedb/StoneDBErrors.java +++ /dev/null @@ -1,63 +0,0 @@ -package sqlancer.stonedb; - -import java.util.ArrayList; -import java.util.List; - -import sqlancer.common.query.ExpectedErrors; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; - -public final class StoneDBErrors { - private StoneDBErrors() { - } - - public static List getExpectedExpressionErrors(StoneDBGlobalState globalState) { - ArrayList errors = new ArrayList<>(); - - // java.sql.SQLException: Incorrect DATE value: '292269055-12-02' - errors.add("Incorrect DATE value: "); - // java.sql.SQLException: Incorrect string value: '\xBC\xE7\xC9\x91\x05R...' for - // column 'c1' at row 1 - errors.add("Incorrect string value: "); - // java.sql.SQLException: Incorrect integer value: 'ST' for column 'c1' at row 1 - errors.add("Incorrect integer value: "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Truncated - // incorrect INTEGER value: '#Q' - errors.add("Data truncation: Truncated incorrect INTEGER value: "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: BIGINT - // value is out of range in - // '-((`database0`.`t0`.`c1` >> (not(`database0`.`t0`.`c1`))))' - errors.add("Data truncation: BIGINT value is out of range in "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: BIGINT - // UNSIGNED value is out of range in - // '(`database10`.`t0`.`c0` + (`database10`.`t0`.`c0` & (not(0.5))))' - errors.add("Data truncation: BIGINT UNSIGNED value is out of range in "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect - // time value: '0Sly6xqF0' for - // column 'c1' at row 1 - errors.add("Data truncation: Incorrect time value: "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: DOUBLE - // value is out of range in - // '(`database0`.`t0`.`c0` * `database0`.`t0`.`c0`)' - errors.add("Data truncation: DOUBLE value is out of range in "); - // java.sql.SQLException: Numeric result of an expression is too large and - // cannot be handled by tianmu. - errors.add("Numeric result of an expression is too large and cannot be handled by tianmu."); - // java.sql.SQLSyntaxErrorException: Unknown column '1020726100' in 'order - // clause' - errors.add("Unknown column "); - if (globalState.getDbmsSpecificOptions().test80Version) { - // Caused by: java.sql.SQLException: Incorrect DATETIME value: '292269055-12-02 - // 16:47:04' - errors.add("Incorrect DATETIME value: "); - // Caused by: java.sql.SQLException: Incorrect TIMESTAMP value: '292269055-12-02 - // 16:47:04' - errors.add("Incorrect TIMESTAMP value: "); - } - - return errors; - } - - public static void addExpectedExpressionErrors(StoneDBGlobalState globalState, ExpectedErrors errors) { - errors.addAll(getExpectedExpressionErrors(globalState)); - } -} diff --git a/src/sqlancer/stonedb/StoneDBOptions.java b/src/sqlancer/stonedb/StoneDBOptions.java deleted file mode 100644 index 0c9d8816a..000000000 --- a/src/sqlancer/stonedb/StoneDBOptions.java +++ /dev/null @@ -1,99 +0,0 @@ -package sqlancer.stonedb; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.Parameters; - -import sqlancer.DBMSSpecificOptions; -import sqlancer.OracleFactory; -import sqlancer.common.oracle.CompositeTestOracle; -import sqlancer.common.oracle.TestOracle; -import sqlancer.stonedb.StoneDBOptions.StoneDBOracleFactory; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.oracle.StoneDBAggregateOracle; -import sqlancer.stonedb.oracle.StoneDBFuzzOracle; -import sqlancer.stonedb.oracle.StoneDBNoRECOracle; -import sqlancer.stonedb.oracle.StoneDBQueryPartitioningDistinctTester; -import sqlancer.stonedb.oracle.StoneDBQueryPartitioningGroupByTester; -import sqlancer.stonedb.oracle.StoneDBQueryPartitioningHavingTester; -import sqlancer.stonedb.oracle.StoneDBQueryPartitioningWhereTester; - -@Parameters(separators = "=", commandDescription = "StoneDB (default host: " + StoneDBOptions.DEFAULT_HOST - + ", default port: " + StoneDBOptions.DEFAULT_PORT + ")") -public class StoneDBOptions implements DBMSSpecificOptions { - public static final String DEFAULT_HOST = "localhost"; - public static final int DEFAULT_PORT = 3306; - - @Parameter(names = "--test-8-version", description = "Let SQLancer test the StoneDB 8.0, otherwise, SQLancer will test the StoneDB 5.7", arity = 1) - public boolean test80Version = true; - - @Parameter(names = "--oracle") - public List oracles = List.of(StoneDBOracleFactory.NOREC); - - public enum StoneDBOracleFactory implements OracleFactory { - FUZZER { - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - return new StoneDBFuzzOracle(globalState); - } - }, - NOREC { - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - return new StoneDBNoRECOracle(globalState); - } - }, - QUERY_PARTITIONING { - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - List> oracles = new ArrayList<>(); - oracles.add(new StoneDBQueryPartitioningWhereTester(globalState)); - oracles.add(new StoneDBQueryPartitioningHavingTester(globalState)); - oracles.add(new StoneDBAggregateOracle(globalState)); - oracles.add(new StoneDBQueryPartitioningDistinctTester(globalState)); - oracles.add(new StoneDBQueryPartitioningGroupByTester(globalState)); - return new CompositeTestOracle<>(oracles, globalState); - } - }, - HAVING { - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - return new StoneDBQueryPartitioningHavingTester(globalState); - } - }, - WHERE { - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - return new StoneDBQueryPartitioningWhereTester(globalState); - } - }, - GROUP_BY { - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - return new StoneDBQueryPartitioningGroupByTester(globalState); - } - }, - AGGREGATE { - - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - return new StoneDBAggregateOracle(globalState); - } - - }, - DISTINCT { - @Override - public TestOracle create(StoneDBGlobalState globalState) throws SQLException { - return new StoneDBQueryPartitioningDistinctTester(globalState); - } - } - } - - @Override - public List getTestOracleFactory() { - return oracles; - } -} diff --git a/src/sqlancer/stonedb/StoneDBProvider.java b/src/sqlancer/stonedb/StoneDBProvider.java deleted file mode 100644 index e4d9c46f8..000000000 --- a/src/sqlancer/stonedb/StoneDBProvider.java +++ /dev/null @@ -1,157 +0,0 @@ -package sqlancer.stonedb; - -import static sqlancer.stonedb.StoneDBBugs.bugNotReported2; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.Statement; - -import com.google.auto.service.AutoService; - -import sqlancer.AbstractAction; -import sqlancer.DatabaseProvider; -import sqlancer.IgnoreMeException; -import sqlancer.MainOptions; -import sqlancer.Randomly; -import sqlancer.SQLConnection; -import sqlancer.SQLGlobalState; -import sqlancer.SQLProviderAdapter; -import sqlancer.StatementExecutor; -import sqlancer.common.DBMSCommon; -import sqlancer.common.query.Query; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.common.query.SQLQueryProvider; -import sqlancer.stonedb.gen.StoneDBIndexCreateGenerator; -import sqlancer.stonedb.gen.StoneDBIndexDropGenerator; -import sqlancer.stonedb.gen.StoneDBTableAlterGenerator; -import sqlancer.stonedb.gen.StoneDBTableCreateGenerator; -import sqlancer.stonedb.gen.StoneDBTableDeleteGenerator; -import sqlancer.stonedb.gen.StoneDBTableInsertGenerator; -import sqlancer.stonedb.gen.StoneDBTableUpdateGenerator; -import sqlancer.stonedb.gen.StoneDBViewCreateGenerator; - -@AutoService(DatabaseProvider.class) -public class StoneDBProvider extends SQLProviderAdapter { - - public StoneDBProvider() { - super(StoneDBGlobalState.class, StoneDBOptions.class); - } - - public static class StoneDBGlobalState extends SQLGlobalState { - @Override - protected StoneDBSchema readSchema() throws Exception { - return StoneDBSchema.fromConnection(getConnection(), getDatabaseName()); - } - } - - enum Action implements AbstractAction { - TABLES_SHOW((g) -> new SQLQueryAdapter("SHOW TABLES")), // - TABLE_ALTER(StoneDBTableAlterGenerator::generate), // - TABLE_CREATE((g) -> { - String tableName = DBMSCommon.createTableName(g.getSchema().getDatabaseTables().size()); - return StoneDBTableCreateGenerator.generate(g, tableName); - }), // - TABLE_DELETE(StoneDBTableDeleteGenerator::generate), // - TABLE_UPDATE(StoneDBTableUpdateGenerator::generate), // - INDEX_CREATE(StoneDBIndexCreateGenerator::generate), // - INDEX_DROP(StoneDBIndexDropGenerator::generate), // - TABLE_INSERT(StoneDBTableInsertGenerator::generate), // - - VIEW_CREATE((g) -> { - String viewName = g.getSchema().getFreeViewName(); - return StoneDBViewCreateGenerator.generate(g, viewName); - }); - - private final SQLQueryProvider sqlQueryProvider; - - Action(SQLQueryProvider sqlQueryProvider) { - this.sqlQueryProvider = sqlQueryProvider; - } - - @Override - public Query getQuery(StoneDBGlobalState globalState) throws Exception { - return sqlQueryProvider.getQuery(globalState); - } - } - - private static int mapActions(StoneDBGlobalState globalState, Action a) { - Randomly r = globalState.getRandomly(); - switch (a) { - case TABLES_SHOW: - return r.getInteger(0, 1); - case TABLE_ALTER: - return r.getInteger(0, 5); - case TABLE_CREATE: - return r.getInteger(0, 1); - case TABLE_DELETE: - if (bugNotReported2) { - return 0; - } - return r.getInteger(0, 10); - case TABLE_INSERT: - return r.getInteger(0, globalState.getOptions().getMaxNumberInserts()); - case TABLE_UPDATE: - return r.getInteger(0, 1); - case INDEX_CREATE: - return r.getInteger(0, 1); - case INDEX_DROP: - return r.getInteger(0, 1); - case VIEW_CREATE: - return r.getInteger(0, 1); - default: - throw new AssertionError(a); - } - } - - @Override - public void generateDatabase(StoneDBGlobalState globalState) throws Exception { - while (globalState.getSchema().getDatabaseTables().size() < Randomly.smallNumber() + 1) { - String tableName = DBMSCommon.createTableName(globalState.getSchema().getDatabaseTables().size()); - SQLQueryAdapter createTable = StoneDBTableCreateGenerator.generate(globalState, tableName); - globalState.executeStatement(createTable); - } - StatementExecutor se = new StatementExecutor<>(globalState, Action.values(), - StoneDBProvider::mapActions, (q) -> { - if (globalState.getSchema().getDatabaseTables().isEmpty()) { - throw new IgnoreMeException(); - } - }); - se.executeStatements(); - } - - @Override - public SQLConnection createDatabase(StoneDBGlobalState globalState) throws Exception { - String username = globalState.getOptions().getUserName(); - String password = globalState.getOptions().getPassword(); - String host = globalState.getOptions().getHost(); - int port = globalState.getOptions().getPort(); - if (host == null) { - host = StoneDBOptions.DEFAULT_HOST; - } - if (port == MainOptions.NO_SET_PORT) { - port = StoneDBOptions.DEFAULT_PORT; - } - String databaseName = globalState.getDatabaseName(); - globalState.getState().logStatement("DROP DATABASE IF EXISTS " + databaseName); - globalState.getState().logStatement("CREATE DATABASE " + databaseName); - globalState.getState().logStatement("USE " + databaseName); - String url = String.format("jdbc:mysql://%s:%d?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true", - host, port); - Connection con = DriverManager.getConnection(url, username, password); - try (Statement s = con.createStatement()) { - s.execute("DROP DATABASE IF EXISTS " + databaseName); - } - try (Statement s = con.createStatement()) { - s.execute("CREATE DATABASE " + databaseName); - } - try (Statement s = con.createStatement()) { - s.execute("USE " + databaseName); - } - return new SQLConnection(con); - } - - @Override - public String getDBMSName() { - return "stonedb"; - } -} diff --git a/src/sqlancer/stonedb/StoneDBSchema.java b/src/sqlancer/stonedb/StoneDBSchema.java deleted file mode 100644 index 346031fba..000000000 --- a/src/sqlancer/stonedb/StoneDBSchema.java +++ /dev/null @@ -1,441 +0,0 @@ -package sqlancer.stonedb; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import sqlancer.Randomly; -import sqlancer.SQLConnection; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.schema.AbstractRelationalTable; -import sqlancer.common.schema.AbstractSchema; -import sqlancer.common.schema.AbstractTableColumn; -import sqlancer.common.schema.AbstractTables; -import sqlancer.common.schema.TableIndex; -import sqlancer.stonedb.ast.StoneDBConstant; -import sqlancer.stonedb.ast.StoneDBExpression; - -public class StoneDBSchema extends AbstractSchema { - - public enum StoneDBDataType { - - NULL, TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, FLOAT, DOUBLE, DECIMAL, YEAR, TIME, DATE, DATETIME, TIMESTAMP, - CHAR, VARCHAR, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT, BINARY, VARBINARY, TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB; - - public static StoneDBDataType getRandomWithoutNull() { - List collect = Stream.of(values()).filter(c -> c != NULL).collect(Collectors.toList()); - return Randomly.fromList(collect); - } - - public static StoneDBDataType getRandom() { - return Randomly.fromOptions(values()); - } - - public static Node getRandomValue(StoneDBDataType dataType, Randomly r) { - switch (dataType) { - case TINYINT: - break; - case SMALLINT: - break; - case MEDIUMINT: - break; - case INT: - return StoneDBConstant.createIntConstant((int) Randomly.getNonCachedInteger()); - case BIGINT: - break; - case FLOAT: - break; - case DOUBLE: - return StoneDBConstant.createDoubleConstant(Randomly.getUncachedDouble()); - case DECIMAL: - break; - case YEAR: - break; - case TIME: - break; - case DATE: - return StoneDBConstant.createDateConstant(Randomly.getNonCachedInteger()); - case DATETIME: - break; - case TIMESTAMP: - return StoneDBConstant.createTimestampConstant(Randomly.getNonCachedInteger()); - case CHAR: - break; - case VARCHAR: - break; - case TINYTEXT: - break; - case TEXT: - return StoneDBConstant.createTextConstant(r.getString()); - case MEDIUMTEXT: - break; - case LONGTEXT: - break; - case BINARY: - break; - case VARBINARY: - break; - case TINYBLOB: - break; - case BLOB: - break; - case MEDIUMBLOB: - break; - case LONGBLOB: - break; - default: - throw new AssertionError(); - } - return null; - } - - public static String getTypeAndValue(StoneDBDataType dataType, Randomly r) { - StringBuilder sb = new StringBuilder(); - switch (dataType) { - case TINYINT: - return "TINYINT"; - case SMALLINT: - return "SMALLINT"; - case MEDIUMINT: - return "MEDIUMINT"; - case INT: - return "INT"; - case BIGINT: - return "BIGINT"; - case FLOAT: - sb.append("FLOAT"); - optionallyAddPrecisionAndScale(sb); - return sb.toString(); - case DOUBLE: - sb.append("DOUBLE"); - optionallyAddPrecisionAndScale(sb); - return sb.toString(); - case DECIMAL: - return "DECIMAL"; // The default value is P(10,0); - case YEAR: - return "YEAR"; - case TIME: - return "TIME"; - case DATE: - return "DATE"; - case DATETIME: - return "DATETIME"; - case TIMESTAMP: - return "TIMESTAMP"; - case CHAR: - sb.append("CHAR").append(Randomly.fromOptions("", "(" + r.getInteger(0, 255) + ")")); - return sb.toString(); - case VARCHAR: - sb.append("VARCHAR").append("(").append(r.getInteger(0, 65535)).append(")"); - return sb.toString(); - case TINYTEXT: - return "TINYTEXT"; - case TEXT: - return "TEXT"; - case MEDIUMTEXT: - return "MEDIUMTEXT"; - case LONGTEXT: - return "LONGTEXT"; - case BINARY: - return "BINARY"; - case VARBINARY: - sb.append("VARBINARY").append("(").append(r.getInteger(0, 65535)).append(")"); - return sb.toString(); - case TINYBLOB: - return "TINYBLOB"; - case BLOB: - return "BLOB"; - case MEDIUMBLOB: - return "MEDIUMBLOB"; - case LONGBLOB: - return "LONGBLOB"; - default: - throw new AssertionError(); - } - } - - private static void optionallyAddPrecisionAndScale(StringBuilder sb) { - if (Randomly.getBoolean()) { - sb.append("("); - // The maximum number of digits (M) for DECIMAL is 65 - long m = Randomly.getNotCachedInteger(1, 65); - sb.append(m); - sb.append(", "); - // The maximum number of supported decimals (D) is 30 - long nCandidate = Randomly.getNotCachedInteger(1, 30); - // For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'c0'). - long n = Math.min(nCandidate, m); - sb.append(n); - sb.append(")"); - } - } - } - - public static class StoneDBTable - extends AbstractRelationalTable { - - public StoneDBTable(String tableName, List columns, List indexes, boolean isView) { - super(tableName, columns, indexes, isView); - } - - public boolean hasPrimaryKey() { - return getColumns().stream().anyMatch(c -> c.isPrimaryKey()); - } - - } - - public static class StoneDBTables extends AbstractTables { - public StoneDBTables(List tables) { - super(tables); - } - } - - public static final class StoneDBIndex extends TableIndex { - private StoneDBIndex(String indexName) { - super(indexName); - } - - public static StoneDBIndex create(String indexName) { - return new StoneDBIndex(indexName); - } - - @Override - public String getIndexName() { - if (super.getIndexName().contentEquals("PRIMARY")) { - return "`PRIMARY`"; - } else { - return super.getIndexName(); - } - } - } - - public static StoneDBSchema fromConnection(SQLConnection con, String databaseName) throws SQLException { - List databaseTables = new ArrayList<>(); - List tableNames = getTableNames(con, databaseName); - for (String tableName : tableNames) { - List databaseColumns = getTableColumns(con, databaseName, tableName); - List indexes = getIndexes(con, databaseName, tableName); - boolean isView = tableName.startsWith("v"); - StoneDBTable t = new StoneDBTable(tableName, databaseColumns, indexes, isView); - for (StoneDBColumn c : databaseColumns) { - c.setTable(t); - } - databaseTables.add(t); - - } - return new StoneDBSchema(databaseTables); - } - - private static List getIndexes(SQLConnection con, String databaseName, String tableName) - throws SQLException { - List indexes = new ArrayList<>(); - try (ResultSet rs = con.createStatement() - .executeQuery("SELECT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = '" - + databaseName + "' AND TABLE_NAME='" + tableName + "';")) { - while (rs.next()) { - String indexName = rs.getString("INDEX_NAME"); - indexes.add(StoneDBIndex.create(indexName)); - } - } - return indexes; - } - - private static List getTableColumns(SQLConnection con, String databaseName, String tableName) - throws SQLException { - List columns = new ArrayList<>(); - try (ResultSet rs = con.createStatement() - .executeQuery("select * from information_schema.columns where table_schema = '" + databaseName - + "' AND TABLE_NAME='" + tableName + "';")) { - while (rs.next()) { - String columnName = rs.getString("COLUMN_NAME"); - String dataType = rs.getString("DATA_TYPE"); - int precision = rs.getInt("NUMERIC_PRECISION"); - boolean isNullable = !rs.getString("IS_NULLABLE").equals("NO"); - boolean isPrimaryKey = rs.getString("COLUMN_KEY").equals("PRI"); - StoneDBColumn c = new StoneDBColumn(columnName, getColumnCompositeDataType(dataType), isPrimaryKey, - isNullable, precision); - columns.add(c); - } - } - return columns; - } - - private static StoneDBCompositeDataType getColumnCompositeDataType(String typeString) { - if (Arrays.stream(StoneDBDataType.values()).noneMatch(e -> e.name().equals(typeString.toUpperCase()))) { - throw new AssertionError(typeString); - } - return new StoneDBCompositeDataType(StoneDBDataType.valueOf(typeString.toUpperCase())); - } - - public static StoneDBDataType getColumnDataType(String typeString) { - if (Arrays.stream(StoneDBDataType.values()).noneMatch(e -> e.name().equals(typeString.toUpperCase()))) { - throw new AssertionError(typeString); - } - return StoneDBDataType.valueOf(typeString.toUpperCase()); - } - - private static List getTableNames(SQLConnection con, String databaseName) throws SQLException { - List tableNames = new ArrayList<>(); - try (ResultSet rs = con.createStatement() - .executeQuery("select TABLE_NAME, ENGINE from information_schema.TABLES where table_schema = '" - + databaseName + "';")) { - while (rs.next()) { - if (rs.getString("ENGINE").equals("TIANMU")) { - tableNames.add(rs.getString("TABLE_NAME")); - } - } - } - return tableNames; - } - - public static class StoneDBColumn extends AbstractTableColumn { - - private final boolean isPrimaryKey; - private final boolean isNullable; - private final int precision; - - public StoneDBColumn(String name, StoneDBCompositeDataType columnType, boolean isPrimaryKey, boolean isNullable, - int precision) { - super(name, null, columnType); - this.isPrimaryKey = isPrimaryKey; - this.isNullable = isNullable; - this.precision = precision; - } - - public boolean isPrimaryKey() { - return isPrimaryKey; - } - - public boolean isNullable() { - return isNullable; - } - - public int getPrecision() { - return precision; - } - - } - - public StoneDBSchema(List databaseTables) { - super(databaseTables); - } - - public static class StoneDBCompositeDataType { - private final StoneDBDataType dataType; - private final int size; - - public StoneDBCompositeDataType(StoneDBDataType dataType, int size) { - this.dataType = dataType; - this.size = size; - } - - public StoneDBCompositeDataType(StoneDBDataType dataType) { - this.dataType = dataType; - int size = -1; - switch (dataType) { - case TINYINT: - size = 1; - break; - case SMALLINT: - size = 2; - break; - case MEDIUMINT: - size = 3; - break; - case INT: - size = 4; - break; - case BIGINT: - size = 8; - break; - case FLOAT: - size = 4; - break; - case DOUBLE: - size = 8; - break; - case DECIMAL: - size = -2; - break; - case YEAR: - size = -2; - break; - case TIME: - size = -2; - break; - case DATE: - size = -2; - break; - case DATETIME: - size = -2; - break; - case TIMESTAMP: - size = -2; - break; - case CHAR: - size = -2; - break; - case VARCHAR: - size = -2; - break; - case TINYTEXT: - size = -2; - break; - case TEXT: - size = -2; - break; - case MEDIUMTEXT: - size = -2; - break; - case LONGTEXT: - size = -2; - break; - case BINARY: - size = -2; - break; - case VARBINARY: - size = -2; - break; - case TINYBLOB: - size = -2; - break; - case BLOB: - size = -2; - break; - case MEDIUMBLOB: - size = -2; - break; - case LONGBLOB: - size = -2; - break; - default: - throw new AssertionError(); - } - this.size = size; - } - - public StoneDBDataType getPrimitiveDataType() { - return dataType; - } - - public int getSize() { - if (size == -1) { - throw new AssertionError(this); - } - return size; - } - - public static StoneDBCompositeDataType getRandomWithoutNull() { - StoneDBDataType type = StoneDBDataType.getRandomWithoutNull(); - return new StoneDBCompositeDataType(type); - } - } - - public StoneDBTables getRandomTableNonEmptyTables() { - return new StoneDBTables(Randomly.nonEmptySubset(getDatabaseTables())); - } -} diff --git a/src/sqlancer/stonedb/StoneDBToStringVisitor.java b/src/sqlancer/stonedb/StoneDBToStringVisitor.java deleted file mode 100644 index 971297ddd..000000000 --- a/src/sqlancer/stonedb/StoneDBToStringVisitor.java +++ /dev/null @@ -1,101 +0,0 @@ -package sqlancer.stonedb; - -import sqlancer.common.ast.newast.NewToStringVisitor; -import sqlancer.common.ast.newast.Node; -import sqlancer.stonedb.StoneDBSchema.StoneDBDataType; -import sqlancer.stonedb.ast.StoneDBConstant; -import sqlancer.stonedb.ast.StoneDBExpression; -import sqlancer.stonedb.ast.StoneDBJoin; -import sqlancer.stonedb.ast.StoneDBSelect; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator.StoneDBCastOperation; - -public class StoneDBToStringVisitor extends NewToStringVisitor { - @Override - public void visitSpecific(Node expr) { - if (expr instanceof StoneDBConstant) { - visit((StoneDBConstant) expr); - } else if (expr instanceof StoneDBSelect) { - visit((StoneDBSelect) expr); - } else if (expr instanceof StoneDBJoin) { - visit((StoneDBJoin) expr); - } else if (expr instanceof StoneDBCastOperation) { - visit((StoneDBCastOperation) expr); - } else { - throw new AssertionError(expr.getClass()); - } - } - - private void visit(StoneDBConstant constant) { - sb.append(constant.toString()); - } - - private void visit(StoneDBSelect select) { - sb.append("SELECT "); - if (select.isDistinct()) { - sb.append("DISTINCT "); - } - visit(select.getFetchColumns()); - sb.append(" FROM "); - visit(select.getFromList()); - if (!select.getFromList().isEmpty() && !select.getJoinList().isEmpty()) { - sb.append(", "); - } - if (!select.getJoinList().isEmpty()) { - visit(select.getJoinList()); - } - if (select.getWhereClause() != null) { - sb.append(" WHERE "); - visit(select.getWhereClause()); - } - if (!select.getGroupByExpressions().isEmpty()) { - sb.append(" GROUP BY "); - visit(select.getGroupByExpressions()); - } - if (select.getHavingClause() != null) { - sb.append(" HAVING "); - visit(select.getHavingClause()); - } - if (!select.getOrderByClauses().isEmpty()) { - sb.append(" ORDER BY "); - visit(select.getOrderByClauses()); - } - if (select.getLimitClause() != null) { - sb.append(" LIMIT "); - visit(select.getLimitClause()); - } - if (select.getOffsetClause() != null) { - sb.append(" OFFSET "); - visit(select.getOffsetClause()); - } - } - - private void visit(StoneDBJoin join) { - visit(join.getLeftTable()); - sb.append(" "); - sb.append(join.getJoinType()); - sb.append(" "); - if (join.getNaturalJoinType() != null) { - sb.append(join.getNaturalJoinType()); - } - sb.append(" JOIN "); - visit(join.getRightTable()); - if (join.getOnCondition() != null) { - sb.append(" ON "); - visit(join.getOnCondition()); - } - } - - private void visit(StoneDBCastOperation cast) { - sb.append("CAST("); - visit(cast.getExpr()); - sb.append(" AS "); - sb.append(cast.getType() == StoneDBDataType.INT ? "UNSIGNED" : cast.getType().toString()); - sb.append(") "); - } - - public static String asString(Node expr) { - StoneDBToStringVisitor visitor = new StoneDBToStringVisitor(); - visitor.visit(expr); - return visitor.get(); - } -} diff --git a/src/sqlancer/stonedb/ast/StoneDBAdvancedFunction.java b/src/sqlancer/stonedb/ast/StoneDBAdvancedFunction.java deleted file mode 100644 index 9c49f2678..000000000 --- a/src/sqlancer/stonedb/ast/StoneDBAdvancedFunction.java +++ /dev/null @@ -1,34 +0,0 @@ -package sqlancer.stonedb.ast; - -import java.util.List; - -import sqlancer.Randomly; -import sqlancer.common.ast.FunctionNode; -import sqlancer.stonedb.ast.StoneDBAdvancedFunction.StoneDBAdvancedFunc; - -public class StoneDBAdvancedFunction extends FunctionNode - implements StoneDBExpression { - - // https://stonedb.io/docs/SQL-reference/functions/advanced-functions - public enum StoneDBAdvancedFunc { - IFNULL(2), IF(3), NULLIF(2), BIN(1), BINARY(1), CONV(3); - - private int nrArgs; - - StoneDBAdvancedFunc(int nrArgs) { - this.nrArgs = nrArgs; - } - - public static StoneDBAdvancedFunc getRandom() { - return Randomly.fromOptions(values()); - } - - public int getNrArgs() { - return nrArgs; - } - } - - protected StoneDBAdvancedFunction(StoneDBAdvancedFunc function, List args) { - super(function, args); - } -} diff --git a/src/sqlancer/stonedb/ast/StoneDBAggregate.java b/src/sqlancer/stonedb/ast/StoneDBAggregate.java deleted file mode 100644 index f65b54d74..000000000 --- a/src/sqlancer/stonedb/ast/StoneDBAggregate.java +++ /dev/null @@ -1,34 +0,0 @@ -package sqlancer.stonedb.ast; - -import java.util.List; - -import sqlancer.Randomly; -import sqlancer.common.ast.FunctionNode; -import sqlancer.stonedb.ast.StoneDBAggregate.StoneDBAggregateFunction; - -public class StoneDBAggregate extends FunctionNode - implements StoneDBExpression { - - // https://stonedb.io/docs/SQL-reference/functions/aggregate-functions/ - public enum StoneDBAggregateFunction { - MAX(1), MIN(1), AVG(1), COUNT(1), SUM(1); - - private int nrArgs; - - StoneDBAggregateFunction(int nrArgs) { - this.nrArgs = nrArgs; - } - - public static StoneDBAggregateFunction getRandom() { - return Randomly.fromOptions(values()); - } - - public int getNrArgs() { - return nrArgs; - } - } - - protected StoneDBAggregate(StoneDBAggregateFunction function, List args) { - super(function, args); - } -} diff --git a/src/sqlancer/stonedb/ast/StoneDBConstant.java b/src/sqlancer/stonedb/ast/StoneDBConstant.java deleted file mode 100644 index 6760bc25c..000000000 --- a/src/sqlancer/stonedb/ast/StoneDBConstant.java +++ /dev/null @@ -1,211 +0,0 @@ -package sqlancer.stonedb.ast; - -import static sqlancer.stonedb.StoneDBBugs.bugNotReported1; - -import java.sql.Timestamp; -import java.text.SimpleDateFormat; - -import sqlancer.common.ast.newast.Node; - -public class StoneDBConstant implements Node { - - private StoneDBConstant() { - } - - public static class StoneDBNullConstant extends StoneDBConstant { - @Override - public String toString() { - return "NULL"; - } - } - - public static Node createNullConstant() { - return new StoneDBNullConstant(); - } - - public static class StoneDBIntConstant extends StoneDBConstant { - private final Integer value; - - public StoneDBIntConstant(int value) { - this.value = value; - } - - @Override - public String toString() { - if (value.equals(Integer.MIN_VALUE)) { - return "INT_NULL"; - } - return String.valueOf(value); - } - } - - public static Node createIntConstant(int val) { - return new StoneDBIntConstant(val); - } - - public static class StoneDBBigIntConstant extends StoneDBConstant { - private final Long value; - - public StoneDBBigIntConstant(long value) { - this.value = value; - } - - @Override - public String toString() { - // For INT type: -2147483648 is reserved to indicate INT_NULL in Tianmu engine, Minimum Value Signed start - // from -2147483647 - // refer: https://stonedb.io/docs/SQL-reference/data-types - if (value.equals(Long.MIN_VALUE)) { - return "BIGINT_NULL"; - } - return String.valueOf(value); - } - } - - public static class StoneDBDoubleConstant extends StoneDBConstant { - - private final Double value; - - public StoneDBDoubleConstant(double value) { - this.value = value; - } - - public double getValue() { - return value; - } - - @Override - public String toString() { - if (value == Double.POSITIVE_INFINITY) { - return "'+Inf'"; - } else if (value == Double.NEGATIVE_INFINITY) { - return "'-Inf'"; - } - return String.valueOf(value); - } - - } - - public static Node createDoubleConstant(double val) { - if (bugNotReported1 && val < 0.5 && val > 0) { - return new StoneDBDoubleConstant(0.5); - } - return new StoneDBDoubleConstant(val); - } - - public static class StoneDBTextConstant extends StoneDBConstant { - - private final String value; - - public StoneDBTextConstant(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return "'" + value.replace("'", "''") + "'"; - } - - } - - public static Node createTextConstant(String text) { - return new StoneDBTextConstant(text); - } - - public static class StoneDBBitConstant extends StoneDBConstant { - - private final String value; - - public StoneDBBitConstant(long value) { - this.value = Long.toBinaryString(value); - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return "B'" + value + "'"; - } - - } - - public static class StoneDBDateConstant extends StoneDBConstant { - - public String textRepr; - - public StoneDBDateConstant(long val) { - Timestamp timestamp = new Timestamp(val); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - textRepr = dateFormat.format(timestamp); - } - - public String getValue() { - return textRepr; - } - - @Override - public String toString() { - return String.format("DATE '%s'", textRepr); - } - - } - - public static Node createDateConstant(long integer) { - return new StoneDBDateConstant(integer); - } - - public static class StoneDBTimestampConstant extends StoneDBConstant { - - public String textRepr; - - public StoneDBTimestampConstant(long val) { - Timestamp timestamp = new Timestamp(val); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - textRepr = dateFormat.format(timestamp); - } - - public String getValue() { - return textRepr; - } - - @Override - public String toString() { - return String.format("TIMESTAMP '%s'", textRepr); - } - - } - - public static Node createTimestampConstant(long integer) { - return new StoneDBTimestampConstant(integer); - } - - public static class StoneDBBooleanConstant extends StoneDBConstant { - - private final boolean value; - - public StoneDBBooleanConstant(boolean value) { - this.value = value; - } - - public boolean getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - } - - public static Node createBooleanConstant(boolean val) { - return new StoneDBBooleanConstant(val); - } - -} diff --git a/src/sqlancer/stonedb/ast/StoneDBExpression.java b/src/sqlancer/stonedb/ast/StoneDBExpression.java deleted file mode 100644 index fb8e75124..000000000 --- a/src/sqlancer/stonedb/ast/StoneDBExpression.java +++ /dev/null @@ -1,4 +0,0 @@ -package sqlancer.stonedb.ast; - -public interface StoneDBExpression { -} diff --git a/src/sqlancer/stonedb/ast/StoneDBJoin.java b/src/sqlancer/stonedb/ast/StoneDBJoin.java deleted file mode 100644 index 8bfff08ee..000000000 --- a/src/sqlancer/stonedb/ast/StoneDBJoin.java +++ /dev/null @@ -1,126 +0,0 @@ -package sqlancer.stonedb.ast; - -import java.util.ArrayList; -import java.util.List; - -import sqlancer.Randomly; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.ast.newast.TableReferenceNode; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator; - -public class StoneDBJoin implements Node { - - public enum JoinType { - INNER, NATURAL, LEFT, RIGHT; - - public static JoinType getRandom() { - return Randomly.fromOptions(values()); - } - } - - public enum NaturalJoinType { - LEFT, RIGHT; - - public static NaturalJoinType getRandom() { - return Randomly.fromOptions(values()); - } - } - - private final TableReferenceNode leftTable; - private final TableReferenceNode rightTable; - private final JoinType joinType; - private final Node onCondition; - private NaturalJoinType naturalJoinType; - - public StoneDBJoin(TableReferenceNode leftTable, - TableReferenceNode rightTable, JoinType joinType, - Node onCondition) { - this.leftTable = leftTable; - this.rightTable = rightTable; - this.joinType = joinType; - this.onCondition = onCondition; - } - - public TableReferenceNode getLeftTable() { - return leftTable; - } - - public TableReferenceNode getRightTable() { - return rightTable; - } - - public JoinType getJoinType() { - return joinType; - } - - public Node getOnCondition() { - return onCondition; - } - - public NaturalJoinType getNaturalJoinType() { - return naturalJoinType; - } - - public void setNaturalJoinType(NaturalJoinType naturalJoinType) { - this.naturalJoinType = naturalJoinType; - } - - public static List> getJoins( - List> tableList, StoneDBGlobalState globalState) { - List> joinExpressions = new ArrayList<>(); - while (tableList.size() >= 2 && Randomly.getBooleanWithRatherLowProbability()) { - // get two tables to join - TableReferenceNode leftTable = tableList.remove(0); - TableReferenceNode rightTable = tableList.remove(0); - // store all columns in the above two tables - List columns = new ArrayList<>(leftTable.getTable().getColumns()); - columns.addAll(rightTable.getTable().getColumns()); - // create a join generator - StoneDBExpressionGenerator joinGen = new StoneDBExpressionGenerator(globalState).setColumns(columns); - switch (StoneDBJoin.JoinType.getRandom()) { - case INNER: - joinExpressions.add(StoneDBJoin.createInnerJoin(leftTable, rightTable, joinGen.generateExpression())); - break; - case NATURAL: - joinExpressions.add(StoneDBJoin.createNaturalJoin(leftTable, rightTable, NaturalJoinType.getRandom())); - break; - case LEFT: - joinExpressions - .add(StoneDBJoin.createLeftOuterJoin(leftTable, rightTable, joinGen.generateExpression())); - break; - case RIGHT: - joinExpressions - .add(StoneDBJoin.createRightOuterJoin(leftTable, rightTable, joinGen.generateExpression())); - break; - default: - throw new AssertionError(); - } - } - return joinExpressions; - } - - public static StoneDBJoin createRightOuterJoin(TableReferenceNode left, - TableReferenceNode right, Node onClause) { - return new StoneDBJoin(left, right, JoinType.RIGHT, onClause); - } - - public static StoneDBJoin createLeftOuterJoin(TableReferenceNode left, - TableReferenceNode right, Node onClause) { - return new StoneDBJoin(left, right, JoinType.LEFT, onClause); - } - - public static StoneDBJoin createInnerJoin(TableReferenceNode left, - TableReferenceNode right, Node onClause) { - return new StoneDBJoin(left, right, JoinType.INNER, onClause); - } - - public static Node createNaturalJoin(TableReferenceNode left, - TableReferenceNode right, NaturalJoinType naturalJoinType) { - StoneDBJoin join = new StoneDBJoin(left, right, JoinType.NATURAL, null); - join.setNaturalJoinType(naturalJoinType); - return join; - } -} diff --git a/src/sqlancer/stonedb/ast/StoneDBSelect.java b/src/sqlancer/stonedb/ast/StoneDBSelect.java deleted file mode 100644 index 081106260..000000000 --- a/src/sqlancer/stonedb/ast/StoneDBSelect.java +++ /dev/null @@ -1,17 +0,0 @@ -package sqlancer.stonedb.ast; - -import sqlancer.common.ast.SelectBase; -import sqlancer.common.ast.newast.Node; - -public class StoneDBSelect extends SelectBase> implements Node { - - private boolean isDistinct; - - public void setDistinct(boolean isDistinct) { - this.isDistinct = isDistinct; - } - - public boolean isDistinct() { - return isDistinct; - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBExpressionGenerator.java b/src/sqlancer/stonedb/gen/StoneDBExpressionGenerator.java deleted file mode 100644 index 3e1dcd348..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBExpressionGenerator.java +++ /dev/null @@ -1,340 +0,0 @@ -package sqlancer.stonedb.gen; - -import static sqlancer.stonedb.StoneDBBugs.bug1942; -import static sqlancer.stonedb.StoneDBBugs.bugNotReported3; -import static sqlancer.stonedb.StoneDBBugs.bugNotReported6; -import static sqlancer.stonedb.StoneDBBugs.bugNotReportedXOR; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import sqlancer.IgnoreMeException; -import sqlancer.Randomly; -import sqlancer.common.ast.BinaryOperatorNode.Operator; -import sqlancer.common.ast.newast.ColumnReferenceNode; -import sqlancer.common.ast.newast.NewBetweenOperatorNode; -import sqlancer.common.ast.newast.NewBinaryOperatorNode; -import sqlancer.common.ast.newast.NewCaseOperatorNode; -import sqlancer.common.ast.newast.NewFunctionNode; -import sqlancer.common.ast.newast.NewInOperatorNode; -import sqlancer.common.ast.newast.NewUnaryPostfixOperatorNode; -import sqlancer.common.ast.newast.NewUnaryPrefixOperatorNode; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.gen.UntypedExpressionGenerator; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBDataType; -import sqlancer.stonedb.ast.StoneDBAdvancedFunction.StoneDBAdvancedFunc; -import sqlancer.stonedb.ast.StoneDBAggregate.StoneDBAggregateFunction; -import sqlancer.stonedb.ast.StoneDBConstant; -import sqlancer.stonedb.ast.StoneDBExpression; - -public class StoneDBExpressionGenerator extends UntypedExpressionGenerator, StoneDBColumn> { - - private final StoneDBGlobalState globalState; - - public StoneDBExpressionGenerator(StoneDBGlobalState globalState) { - this.globalState = globalState; - } - - private enum Expression { - UNARY_PREFIX, UNARY_POSTFIX, BINARY_COMPARISON, BINARY_LOGICAL, BINARY_ARITHMETIC, BINARY_BITWISE, BETWEEN, IN, - NOT_IN, CASE - } - - public static class StoneDBCastOperation implements Node { - Node expr; - StoneDBDataType type; - - public StoneDBCastOperation(Node expr, StoneDBDataType type) { - this.expr = expr; - this.type = type; - } - - public Node getExpr() { - return expr; - } - - public StoneDBDataType getType() { - return type; - } - } - - @Override - public Node negatePredicate(Node predicate) { - return new NewUnaryPrefixOperatorNode<>(predicate, StoneDBUnaryPrefixOperator.NOT); - } - - @Override - public Node isNull(Node expr) { - return new NewUnaryPostfixOperatorNode<>(expr, StoneDBUnaryPostfixOperator.IS_NULL); - } - - @Override - public Node generateConstant() { - if (Randomly.getBooleanWithSmallProbability()) { - return StoneDBConstant.createNullConstant(); - } - StoneDBDataType type = StoneDBDataType.getRandomWithoutNull(); - return generateConstant(type); - } - - public Node generateConstant(StoneDBDataType dataType) { - switch (dataType) { - case INT: - return StoneDBConstant - .createIntConstant(globalState.getRandomly().getInteger(Integer.MIN_VALUE + 1, Integer.MAX_VALUE)); - case DATE: - return StoneDBConstant.createDateConstant(globalState.getRandomly().getInteger()); - case TIMESTAMP: - return StoneDBConstant.createTimestampConstant(globalState.getRandomly().getInteger()); - case VARCHAR: - return StoneDBConstant.createTextConstant(globalState.getRandomly().getString()); - case DOUBLE: - return StoneDBConstant.createDoubleConstant(globalState.getRandomly().getDouble()); - default: - throw new IgnoreMeException(); - } - } - - public Node generateConstant(StoneDBDataType dataType, boolean isNullable) { - if (isNullable && Randomly.getBooleanWithSmallProbability()) { - generateConstant(StoneDBDataType.NULL); - } - return generateConstant(dataType); - } - - @Override - protected Node generateExpression(int depth) { - if (depth >= globalState.getOptions().getMaxExpressionDepth() || Randomly.getBoolean()) { - return generateLeafNode(); - } - if (allowAggregates && Randomly.getBoolean()) { - StoneDBAggregateFunction aggregateFunction = StoneDBAggregateFunction.getRandom(); - allowAggregates = false; - return new NewFunctionNode<>(generateExpressions(aggregateFunction.getNrArgs(), depth + 1), - aggregateFunction); - } - if (Randomly.getBooleanWithRatherLowProbability()) { - StoneDBAdvancedFunc advancedFunction = StoneDBAdvancedFunc.getRandom(); - return new NewFunctionNode<>(generateExpressions(advancedFunction.getNrArgs(), depth + 1), - advancedFunction); - } - List possibleOptions = new ArrayList<>(Arrays.asList(Expression.values())); - Expression expr = Randomly.fromList(possibleOptions); - Operator op; - switch (expr) { - case UNARY_PREFIX: - op = StoneDBUnaryPrefixOperator.getRandom(); - return new NewUnaryPrefixOperatorNode<>(generateExpression(depth + 1), op); - case UNARY_POSTFIX: - if (!bug1942) { - op = StoneDBUnaryPostfixOperator.getRandom(); - } else if (!bugNotReported3) { - op = StoneDBUnaryPostfixOperator.IS_NULL; - } else { - throw new IgnoreMeException(); - } - return new NewUnaryPostfixOperatorNode<>(generateExpression(depth + 1), op); - case BINARY_COMPARISON: - if (!bugNotReported6) { - op = StoneDBBinaryComparisonOperator.getRandom(); - } else { - throw new IgnoreMeException(); - } - return new NewBinaryOperatorNode<>(generateExpression(depth + 1), generateExpression(depth + 1), op); - case IN: - return new NewInOperatorNode<>(generateExpression(depth + 1), - generateExpressions(Randomly.smallNumber() + 1, depth + 1), false); - case NOT_IN: - return new NewInOperatorNode<>(generateExpression(depth + 1), - generateExpressions(Randomly.smallNumber() + 1, depth + 1), true); - case BINARY_LOGICAL: - if (bugNotReportedXOR) { - op = Randomly.fromList(Arrays.stream(StoneDBBinaryLogicalOperator.values()) - .filter(p -> p != StoneDBBinaryLogicalOperator.XOR).collect(Collectors.toList())); - } else { - op = StoneDBBinaryLogicalOperator.getRandom(); - } - return new NewBinaryOperatorNode<>(generateExpression(depth + 1), generateExpression(depth + 1), op); - case BINARY_ARITHMETIC: - op = StoneDBBinaryArithmeticOperator.getRandom(); - return new NewBinaryOperatorNode<>(generateExpression(depth + 1), generateExpression(depth + 1), op); - case BINARY_BITWISE: - op = StoneDBBinaryBitwiseOperator.getRandom(); - return new NewBinaryOperatorNode<>(generateExpression(depth + 1), generateExpression(depth + 1), op); - case BETWEEN: - return new NewBetweenOperatorNode<>(generateExpression(depth + 1), generateExpression(depth + 1), - generateExpression(depth + 1), Randomly.getBoolean()); - case CASE: - int nr = Randomly.smallNumber() + 1; - return new NewCaseOperatorNode<>(generateExpression(depth + 1), generateExpressions(nr, depth + 1), - generateExpressions(nr, depth + 1), generateExpression(depth + 1)); - default: - throw new AssertionError(); - } - } - - @Override - protected Node generateColumn() { - StoneDBColumn column = Randomly.fromList(columns); - return new ColumnReferenceNode<>(column); - } - - protected List> generateColumns() { - int size = globalState.getRandomly().getInteger(1, columns.size()); - Set> set = new HashSet<>(); - while (set.size() < size) { - set.add(generateColumn()); - } - return new ArrayList<>(set); - } - - public enum StoneDBUnaryPrefixOperator implements Operator { - - NOT("NOT"), PLUS("+"), MINUS("-"), INVERSION("!"); - - private final String textRepr; - - StoneDBUnaryPrefixOperator(String textRepr) { - this.textRepr = textRepr; - } - - @Override - public String getTextRepresentation() { - return textRepr; - } - - public static StoneDBUnaryPrefixOperator getRandom() { - return Randomly.fromOptions(values()); - } - } - - public enum StoneDBUnaryPostfixOperator implements Operator { - - IS_NULL("IS NULL"), IS_NOT_NULL("IS NOT NULL"); - - private final String textRepr; - - StoneDBUnaryPostfixOperator(String textRepr) { - this.textRepr = textRepr; - } - - @Override - public String getTextRepresentation() { - return textRepr; - } - - public static StoneDBUnaryPostfixOperator getRandom() { - return Randomly.fromOptions(values()); - } - } - - /* - * Comparison operators supported by StoneDB: https://stonedb.io/docs/SQL-reference/operators/comparison-operators - */ - public enum StoneDBBinaryComparisonOperator implements Operator { - EQUAL("="), GREATER(">"), LESS("<"), GREATER_EQUAL(">="), LESS_EQUAL("<="), - NOT_EQUALS(Randomly.fromList(Arrays.asList("!=", "<>"))), NULL_SAFE_EQUAL("<=>"), LIKE("LIKE"); - - private final String textRepr; - - StoneDBBinaryComparisonOperator(String textRepr) { - this.textRepr = textRepr; - } - - public static Operator getRandom() { - return Randomly.fromOptions(values()); - } - - @Override - public String getTextRepresentation() { - return textRepr; - } - } - - /* - * Logical operators supported by StoneDB: https://stonedb.io/docs/SQL-reference/operators/logical-operators - */ - public enum StoneDBBinaryLogicalOperator implements Operator { - - AND("AND"), OR("OR"), XOR("XOR"); - - private final String textRepr; - - StoneDBBinaryLogicalOperator(String textRepr) { - this.textRepr = textRepr; - } - - public static Operator getRandom() { - return Randomly.fromOptions(values()); - } - - @Override - public String getTextRepresentation() { - return textRepr; - } - - } - - /* - * Arithmetic operators supported by StoneDB: https://stonedb.io/docs/SQL-reference/operators/arithmetic-operators - */ - public enum StoneDBBinaryArithmeticOperator implements Operator { - ADDITION("+"), MINUS("-"), MULTIPLICATION("*"), DIVISION(Randomly.fromList(Arrays.asList("/", " div "))), - MODULO(Randomly.fromList(Arrays.asList("%", " mod "))); - - private final String textRepr; - - StoneDBBinaryArithmeticOperator(String textRepr) { - this.textRepr = textRepr; - } - - public static Operator getRandom() { - return Randomly.fromOptions(values()); - } - - @Override - public String getTextRepresentation() { - return textRepr; - } - - } - - /* - * Bitwise operators supported by StoneDB: https://stonedb.io/docs/SQL-reference/operators/bitwise-operators - */ - public enum StoneDBBinaryBitwiseOperator implements Operator { - AND("&"), OR("|"), XOR("^"), LEFTSHIFT("<<"), RIGHTSHIFT(">>"); - - private final String textRepr; - - StoneDBBinaryBitwiseOperator(String textRepr) { - this.textRepr = textRepr; - } - - public static Operator getRandom() { - return Randomly.fromOptions(values()); - } - - @Override - public String getTextRepresentation() { - return textRepr; - } - - } - - public NewFunctionNode generateAggregateAndArgs( - StoneDBAggregateFunction aggregateFunction) { - return new NewFunctionNode<>(generateExpressions(aggregateFunction.getNrArgs()), aggregateFunction); - } - - public Node generateAggregate() { - StoneDBAggregateFunction aggrFunc = StoneDBAggregateFunction.getRandom(); - return generateAggregateAndArgs(aggrFunc); - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBIndexCreateGenerator.java b/src/sqlancer/stonedb/gen/StoneDBIndexCreateGenerator.java deleted file mode 100644 index 82eab3413..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBIndexCreateGenerator.java +++ /dev/null @@ -1,121 +0,0 @@ -package sqlancer.stonedb.gen; - -import sqlancer.Randomly; -import sqlancer.Randomly.StringGenerationStrategy; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; - -public class StoneDBIndexCreateGenerator { - private final StoneDBGlobalState globalState; - private final Randomly r; - // which table to add index - StoneDBTable table; - private final StringBuilder sb = new StringBuilder(); - ExpectedErrors errors = new ExpectedErrors(); - - public StoneDBIndexCreateGenerator(StoneDBGlobalState globalState) { - this.globalState = globalState; - r = globalState.getRandomly(); - table = globalState.getSchema().getRandomTable(); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState) { - return new StoneDBIndexCreateGenerator(globalState).getQuery(); - } - - private SQLQueryAdapter getQuery() { - sb.append("CREATE "); - // Tianmu engine does not support fulltext index. - sb.append(Randomly.fromOptions("UNIQUE" /* "FULLTEXT" */, "SPATIAL")); - sb.append(" INDEX "); - sb.append(globalState.getSchema().getFreeIndexName()); - if (Randomly.getBoolean()) { - appendIndexType(); - } - sb.append(" ON "); - sb.append(table.getName()); - appendKeyParts(); - appendIndexOption(); - appendAlgoOrLockOption(); - addExpectedErrors(); - return new SQLQueryAdapter(sb.toString(), errors, true); - } - - private void addExpectedErrors() { - // java.sql.SQLException: Tianmu engine does not support unique index. - errors.add("Tianmu engine does not support unique index"); - // java.sql.SQLException: Tianmu engine does not support fulltext index. - errors.add("Tianmu engine does not support fulltext index"); - // java.sql.SQLException: The used table type doesn't support SPATIAL indexes - errors.add("The used table type doesn't support SPATIAL indexes"); - // java.sql.SQLException: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY. - errors.add("ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY."); - // java.sql.SQLSyntaxErrorException: Key column 'c0' doesn't exist in table - errors.add("doesn't exist in table"); - // java.sql.SQLSyntaxErrorException: A SPATIAL index may only contain a geometrical type column - errors.add("A SPATIAL index may only contain a geometrical type column"); - } - - private void appendIndexType() { - // The index_type clause cannot be used for FULLTEXT INDEX or SPATIAL INDEX specifications. - if (sb.toString().contains("FULLTEXT") || sb.toString().contains("SPATIAL")) { - return; - } - if (Randomly.getBoolean()) { - return; - } - sb.append(" USING "); - sb.append(Randomly.fromOptions("BTREE", "HASH")); - } - - private void appendKeyParts() { - int numberOfKeyParts = Randomly.fromOptions(1, 1, 1, 1, table.getColumns().size()); - for (int i = 0; i < numberOfKeyParts; i++) { - appendKeyPart(); - } - } - - private void appendKeyPart() { - sb.append("("); - StoneDBColumn randomColumn = table.getRandomColumn(); - sb.append(randomColumn.getName()); - if (Randomly.getBoolean()) { - sb.append(" (").append(Randomly.smallNumber()).append(")"); - } - if (Randomly.getBoolean()) { - sb.append(Randomly.fromOptions(" ASC", " DESC")); - } - sb.append(")"); - } - - private void appendIndexOption() { - if (Randomly.getBoolean()) { - return; - } - if (Randomly.getBoolean()) { - sb.append(Randomly.fromOptions("KEY_BLOCK_SIZE ", "KEY_BLOCK_SIZE = ")); - sb.append(r.getInteger(1, Math.max(1, Randomly.smallNumber()))); - sb.append(" "); - } - if (Randomly.getBoolean()) { - StringGenerationStrategy strategy = Randomly.StringGenerationStrategy.ALPHANUMERIC; - sb.append(String.format("COMMENT '%s' ", strategy.getString(r))); - } - } - - private void appendAlgoOrLockOption() { - if (Randomly.getBoolean()) { - return; - } - if (Randomly.getBoolean()) { - sb.append(Randomly.fromOptions(" ALGORITHM ", " ALGORITHM = ")); - sb.append(Randomly.fromOptions("DEFAULT", "INPLACE", "COPY")); - } else { - sb.append(Randomly.fromOptions(" LOCK ", " LOCK = ")); - sb.append(Randomly.fromOptions("DEFAULT", "NONE", "SHARED", "EXCLUSIVE")); - } - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBIndexDropGenerator.java b/src/sqlancer/stonedb/gen/StoneDBIndexDropGenerator.java deleted file mode 100644 index dda72c735..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBIndexDropGenerator.java +++ /dev/null @@ -1,47 +0,0 @@ -package sqlancer.stonedb.gen; - -import sqlancer.Randomly; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema; - -public class StoneDBIndexDropGenerator { - // which table to drop index - StoneDBSchema.StoneDBTable table; - private final StringBuilder sb = new StringBuilder(); - ExpectedErrors errors = new ExpectedErrors(); - - public StoneDBIndexDropGenerator(StoneDBGlobalState globalState) { - table = globalState.getSchema().getRandomTable(); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState) { - return new StoneDBIndexDropGenerator(globalState).getQuery(); - } - - private SQLQueryAdapter getQuery() { - if (!table.hasIndexes()) { - return null; - } - sb.append("DROP INDEX "); - sb.append(table.getRandomIndex().getIndexName()); - sb.append(" ON "); - sb.append(table.getName()); - appendAlgoOrLockOption(); - return new SQLQueryAdapter(sb.toString(), errors); - } - - private void appendAlgoOrLockOption() { - if (Randomly.getBoolean()) { - return; - } - if (Randomly.getBoolean()) { - sb.append(Randomly.fromOptions(" ALGORITHM ", " ALGORITHM = ")); - sb.append(Randomly.fromOptions("DEFAULT", "INPLACE", "COPY")); - } else { - sb.append(Randomly.fromOptions(" LOCK ", " LOCK = ")); - sb.append(Randomly.fromOptions("DEFAULT", "NONE", "SHARED", "EXCLUSIVE")); - } - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBTableAlterGenerator.java b/src/sqlancer/stonedb/gen/StoneDBTableAlterGenerator.java deleted file mode 100644 index c37024669..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBTableAlterGenerator.java +++ /dev/null @@ -1,141 +0,0 @@ -package sqlancer.stonedb.gen; - -import java.util.regex.Pattern; - -import sqlancer.Randomly; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBDataType; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; - -public class StoneDBTableAlterGenerator { - private final StoneDBGlobalState globalState; - private final StringBuilder sb = new StringBuilder(); - private final StoneDBTable table; - ExpectedErrors errors = new ExpectedErrors(); - - enum Action { - ADD_COLUMN, ALTER_COLUMN, DROP_COLUMN, CHANGE_COLUMN - } - - public StoneDBTableAlterGenerator(StoneDBGlobalState globalState) { - this.globalState = globalState; - table = globalState.getSchema().getRandomTable(t -> !t.isView()); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState) { - return new StoneDBTableAlterGenerator(globalState).getQuery(); - } - - private SQLQueryAdapter getQuery() { - sb.append("ALTER TABLE "); - sb.append(table.getName()); - sb.append(" "); - appendAlterOption(Randomly.fromOptions(Action.values())); - addExpectedErrors(); - return new SQLQueryAdapter(sb.toString(), errors, true); - } - - private void addExpectedErrors() { - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'c0' at row 2 - errors.addRegex(Pattern.compile("Data truncation: Data too long for column 'c\\d{1,3}' at row \\d{1,3}")); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect datetime value: - // '0.571272522740968' for column 'c1' at row 1 - errors.add("Incorrect datetime value: "); - // java.sql.SQLSyntaxErrorException: Invalid default value for 'c0' - errors.add("Invalid default value for "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for column 'c0' at row - // 2 - errors.add("Data truncation: Out of range value for column "); - // java.sql.SQLSyntaxErrorException: Specified key was too long; max key length is 3072 bytes - errors.add("Specified key was too long; max key length is 3072 bytes"); - // java.sql.SQLSyntaxErrorException: You can't delete all columns with ALTER TABLE; use DROP TABLE instead - errors.add("You can't delete all columns with ALTER TABLE; use DROP TABLE instead"); - // java.sql.SQLSyntaxErrorException: Unknown column 'c0' in 't1' - errors.addRegex(Pattern.compile("Unknown column 'c\\d{1,3}' in 't\\d{1,3}'")); - // java.sql.SQLSyntaxErrorException: BLOB, TEXT, GEOMETRY or JSON column 'c0' can't have a default value - errors.addRegex(Pattern.compile("BLOB, TEXT, GEOMETRY or JSON column 'c\\d{1,3}' can't have a default value")); - // java.sql.SQLSyntaxErrorException: Column length too big for column 'c91' (max = 16383); use BLOB or TEXT - // instead - errors.addRegex(Pattern - .compile("Column length too big for column 'c\\d{1,3}' \\(max = 16383\\); use BLOB or TEXT instead")); - } - - private void appendAlterOption(Action action) { - StoneDBExpressionGenerator generator = new StoneDBExpressionGenerator(globalState) - .setColumns(table.getColumns()); - if (globalState.getDbmsSpecificOptions().test80Version && Randomly.getBooleanWithSmallProbability()) { - sb.append("RENAME COLUMN "); - sb.append(table.getRandomColumn().getName()); - sb.append(" TO "); - sb.append(table.getFreeColumnName()); - } - switch (action) { - case ADD_COLUMN: - sb.append("ADD COLUMN "); - String columnName = table.getFreeColumnName(); - sb.append(" ").append(columnName).append(" "); - sb.append( - StoneDBDataType.getTypeAndValue(StoneDBDataType.getRandomWithoutNull(), globalState.getRandomly())); - // java.sql.SQLSyntaxErrorException: Column length too big for column 'c1' (max = 16383); use BLOB or TEXT - // instead - errors.addRegex(Pattern - .compile("Column length too big for column 'c\\d{1,3}' (max = 16383); use BLOB or TEXT instead")); - if (Randomly.getBoolean()) { - if (Randomly.getBoolean()) { - sb.append(" FIRST"); - } else { - sb.append(" AFTER "); - sb.append(table.getRandomColumn().getName()); - } - } - break; - case DROP_COLUMN: - sb.append(Randomly.fromOptions("DROP COLUMN ", "DROP ")); - sb.append(table.getRandomColumn().getName()); - break; - case ALTER_COLUMN: - sb.append(Randomly.fromOptions("ALTER COLUMN ", "ALTER ")); - StoneDBColumn randomColumn = table.getRandomColumn(); - sb.append(randomColumn.getName()); - if (Randomly.getBoolean()) { - sb.append(" SET DEFAULT ").append(generator - .generateConstant(randomColumn.getType().getPrimitiveDataType(), Randomly.getBoolean())); - } else { - sb.append(" DROP DEFAULT"); - } - break; - case CHANGE_COLUMN: - sb.append(Randomly.fromOptions("CHANGE COLUMN ", "CHANGE ")); - String oldColumnName = table.getRandomColumn().getName(); - String newColumnName = table.getFreeColumnName(); - sb.append(oldColumnName).append(" ").append(newColumnName).append(" "); - errors.add("Incorrect integer value: "); - // java.sql.SQLException: Data truncated for column 'c1' at row 1 - errors.add("Data truncated for column "); - sb.append( - StoneDBDataType.getTypeAndValue(StoneDBDataType.getRandomWithoutNull(), globalState.getRandomly())); - // java.sql.SQLSyntaxErrorException: Column length too big for column 'c1' (max = 16383); use BLOB or TEXT - // instead - errors.addRegex(Pattern - .compile("Column length too big for column 'c\\d{1,3}' (max = 16383); use BLOB or TEXT instead")); - // java.sql.SQLSyntaxErrorException: BLOB column 'c1' can't be used in key specification with the used table - // type - errors.addRegex(Pattern - .compile("BLOB column 'c\\d{1,3}' can't be used in key specification with the used table type")); - if (Randomly.getBoolean()) { - if (Randomly.getBoolean()) { - sb.append(" FIRST"); - } else { - sb.append(" AFTER "); - sb.append(table.getRandomColumn().getName()); - } - } - break; - default: - throw new AssertionError(action); - } - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBTableCreateGenerator.java b/src/sqlancer/stonedb/gen/StoneDBTableCreateGenerator.java deleted file mode 100644 index c288c57fd..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBTableCreateGenerator.java +++ /dev/null @@ -1,266 +0,0 @@ -package sqlancer.stonedb.gen; - -import static sqlancer.stonedb.gen.StoneDBTableCreateGenerator.ColumnOptions.PRIMARY_KEY; -import static sqlancer.stonedb.gen.StoneDBTableCreateGenerator.ColumnOptions.UNIQUE_KEY; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.regex.Pattern; - -import sqlancer.Randomly; -import sqlancer.Randomly.StringGenerationStrategy; -import sqlancer.common.DBMSCommon; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema; -import sqlancer.stonedb.StoneDBSchema.StoneDBDataType; - -public class StoneDBTableCreateGenerator { - // the name of the table to create - private final String tableName; - private final StoneDBSchema schema; - // the name of the columns in the table - private final List columns = new ArrayList<>(); - private final boolean allowPrimaryKey; - private boolean setPrimaryKey; - private final StringBuilder sb = new StringBuilder(); - ExpectedErrors errors = new ExpectedErrors(); - private final Randomly r; - - public StoneDBTableCreateGenerator(StoneDBGlobalState globalState, String tableName) { - this.tableName = tableName; - this.schema = globalState.getSchema(); - allowPrimaryKey = Randomly.getBoolean(); - this.r = globalState.getRandomly(); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState, String tableName) { - return new StoneDBTableCreateGenerator(globalState, tableName).getQuery(); - } - - public SQLQueryAdapter getQuery() { - sb.append(Randomly.fromOptions("CREATE TABLE "/* , "CREATE TEMPORARY TABLE " */)); - if (Randomly.getBoolean()) { - sb.append("IF NOT EXISTS "); - } - sb.append(tableName); - // ues link statement - if (Randomly.getBoolean() && !schema.getDatabaseTables().isEmpty()) { - sb.append(" LIKE "); - sb.append(schema.getRandomTable().getName()); - } else { - appendColumns(); - if (Randomly.getBoolean()) { - sb.append(" "); - appendTableOptions(); - } - } - addExpectedErrors(); - return new SQLQueryAdapter(sb.toString(), errors, true); - } - - private void addExpectedErrors() { - // java.sql.SQLSyntaxErrorException: BLOB/TEXT column 'c0' used in key specification without a key length - errors.add("used in key specification without a key length"); - // java.sql.SQLException: Tianmu engine does not support unique index. - errors.add("Tianmu engine does not support unique index"); - // java.sql.SQLException: BLOB column 'c0' can't be used in key specification with the used table type - errors.add("can't be used in key specification with the used table type"); - // java.sql.SQLSyntaxErrorException: Specified key was too long; max key length is 3072 bytes - errors.add("Specified key was too long; max key length is 3072 bytes"); - // java.sql.SQLSyntaxErrorException: Column length too big for column 'c1' (max = 16383); use BLOB or TEXT - // instead - errors.add("Column length too big for column"); - // BLOB/TEXT column 'c0' used in key specification without a key length - errors.addRegex(Pattern.compile("BLOB/TEXT column 'c.*' used in key specification without a key length")); - } - - private enum TableOptions { - AUTO_INCREMENT, AVG_ROW_LENGTH, CHECKSUM, COMPRESSION, DELAY_KEY_WRITE, /* ENCRYPTION, */ INSERT_METHOD, - KEY_BLOCK_SIZE, MAX_ROWS, MIN_ROWS, PACK_KEYS, STATS_AUTO_RECALC, STATS_PERSISTENT, STATS_SAMPLE_PAGES; - - public static List getRandomTableOptions() { - List options; - // try to ensure that usually, only a few of these options are generated - if (Randomly.getBooleanWithSmallProbability()) { - options = Randomly.subset(TableOptions.values()); - } else { - if (Randomly.getBoolean()) { - options = Collections.emptyList(); - } else { - options = Randomly.nonEmptySubset(Arrays.asList(TableOptions.values()), Randomly.smallNumber()); - } - } - return options; - } - } - - private void appendTableOptions() { - List tableOptions = TableOptions.getRandomTableOptions(); - int i = 0; - for (TableOptions o : tableOptions) { - if (i++ != 0) { - sb.append(", "); - } - switch (o) { - case AUTO_INCREMENT: - sb.append("AUTO_INCREMENT = "); - sb.append(r.getPositiveInteger()); - break; - // The valid range for avg_row_length is [0,4294967295] - case AVG_ROW_LENGTH: - sb.append("AVG_ROW_LENGTH = "); - sb.append(r.getLong(0, 4294967295L + 1)); - break; - case CHECKSUM: - sb.append("CHECKSUM = 1"); - break; - case COMPRESSION: - sb.append("COMPRESSION = '"); - sb.append(Randomly.fromOptions("ZLIB", "LZ4", "NONE")); - sb.append("'"); - break; - case DELAY_KEY_WRITE: - sb.append("DELAY_KEY_WRITE = "); - sb.append(Randomly.fromOptions(0, 1)); - break; - case INSERT_METHOD: - sb.append("INSERT_METHOD = "); - sb.append(Randomly.fromOptions("NO", "FIRST", "LAST")); - break; - // The valid range for key_block_size is [0,65535] - case KEY_BLOCK_SIZE: - sb.append("KEY_BLOCK_SIZE = "); - sb.append(r.getInteger(0, 65535 + 1)); - break; - case MAX_ROWS: - sb.append("MAX_ROWS = "); - sb.append(r.getLong(0, Long.MAX_VALUE)); - break; - case MIN_ROWS: - sb.append("MIN_ROWS = "); - sb.append(r.getLong(1, Long.MAX_VALUE)); - break; - case PACK_KEYS: - sb.append("PACK_KEYS = "); - sb.append(Randomly.fromOptions("1", "0", "DEFAULT")); - break; - case STATS_AUTO_RECALC: - sb.append("STATS_AUTO_RECALC = "); - sb.append(Randomly.fromOptions("1", "0", "DEFAULT")); - break; - case STATS_PERSISTENT: - sb.append("STATS_PERSISTENT = "); - sb.append(Randomly.fromOptions("1", "0", "DEFAULT")); - break; - case STATS_SAMPLE_PAGES: - sb.append("STATS_SAMPLE_PAGES = "); - sb.append(r.getInteger(1, Short.MAX_VALUE)); - break; - default: - throw new AssertionError(o); - } - } - } - - private void appendColumns() { - sb.append("("); - for (int i = 0; i < 1 + Randomly.smallNumber(); i++) { - if (i != 0) { - sb.append(", "); - } - appendColumn(i); - } - sb.append(")"); - } - - private void appendColumn(int columnId) { - String columnName = DBMSCommon.createColumnName(columnId); - columns.add(columnName); - sb.append(columnName); - appendColumnDefinition(); - } - - private void appendColumnDefinition() { - sb.append(" "); - StoneDBDataType randomType = StoneDBDataType.getRandomWithoutNull(); - appendType(randomType); - appendColumnOption(randomType); - } - - protected enum ColumnOptions { - NULL_OR_NOT_NULL, PRIMARY_KEY, UNIQUE_KEY, COMMENT, COLUMN_FORMAT, STORAGE - } - - private void appendColumnOption(StoneDBDataType type) { - boolean isTextType = type == StoneDBDataType.VARCHAR; - boolean isNull = false; - boolean columnHasPrimaryKey = false; - List columnOptions = Randomly.subset(ColumnOptions.values()); - // boolean tableHasNullableColumn; - // if (!columnOptions.contains(ColumnOptions.NULL_OR_NOT_NULL)) { - // tableHasNullableColumn = true; - // } - // only use one key, unique key or primary key, but not both - if (columnOptions.contains(PRIMARY_KEY) && columnOptions.contains(UNIQUE_KEY)) { - columnOptions.remove(Randomly.fromOptions(PRIMARY_KEY, UNIQUE_KEY)); - } - if (isTextType) { - // TODO: restriction due to the limited key length - columnOptions.remove(PRIMARY_KEY); - columnOptions.remove(UNIQUE_KEY); - } - for (ColumnOptions o : columnOptions) { - sb.append(" "); - switch (o) { - case NULL_OR_NOT_NULL: - // PRIMARY KEYs cannot be NULL - if (!columnHasPrimaryKey) { - if (Randomly.getBoolean()) { - sb.append("NULL"); - } - // tableHasNullableColumn = true; - isNull = true; - } else { - sb.append("NOT NULL"); - } - break; - case UNIQUE_KEY: - sb.append("UNIQUE"); - if (Randomly.getBoolean()) { - sb.append(" KEY"); - } - break; - case COMMENT: - StringGenerationStrategy strategy = Randomly.StringGenerationStrategy.ALPHANUMERIC; - sb.append(String.format("COMMENT '%s' ", strategy.getString(r))); - break; - case COLUMN_FORMAT: - sb.append("COLUMN_FORMAT "); - sb.append(Randomly.fromOptions("FIXED", "DYNAMIC", "DEFAULT")); - break; - case STORAGE: - sb.append("STORAGE "); - sb.append(Randomly.fromOptions("DISK", "MEMORY")); - break; - case PRIMARY_KEY: - // PRIMARY KEYs cannot be NULL - if (allowPrimaryKey && !setPrimaryKey && !isNull) { - sb.append("PRIMARY KEY"); - setPrimaryKey = true; - columnHasPrimaryKey = true; - } - break; - default: - throw new AssertionError(); - } - } - } - - private void appendType(StoneDBDataType randomType) { - sb.append(StoneDBDataType.getTypeAndValue(randomType, r)); - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBTableDeleteGenerator.java b/src/sqlancer/stonedb/gen/StoneDBTableDeleteGenerator.java deleted file mode 100644 index 0d8446d4b..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBTableDeleteGenerator.java +++ /dev/null @@ -1,70 +0,0 @@ -package sqlancer.stonedb.gen; - -import java.util.stream.Collectors; - -import sqlancer.Randomly; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.common.schema.AbstractTableColumn; -import sqlancer.stonedb.StoneDBBugs; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.StoneDBToStringVisitor; - -public final class StoneDBTableDeleteGenerator { - private final StoneDBGlobalState globalState; - private final StringBuilder sb = new StringBuilder(); - ExpectedErrors errors = new ExpectedErrors(); - Randomly r; - - private StoneDBTableDeleteGenerator(StoneDBGlobalState globalState) { - this.globalState = globalState; - r = globalState.getRandomly(); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState) { - return new StoneDBTableDeleteGenerator(globalState).getQuery(); - } - - public SQLQueryAdapter getQuery() { - StoneDBTable randomTable = globalState.getSchema().getRandomTable(); - sb.append("DELETE"); - if (Randomly.getBoolean()) { - sb.append(" LOW_PRIORITY"); - } - if (Randomly.getBoolean()) { - sb.append(" QUICK"); - } - if (Randomly.getBoolean()) { - sb.append(" IGNORE"); - } - sb.append(" FROM "); - sb.append(randomTable.getName()); - if (globalState.getDbmsSpecificOptions().test80Version) { - sb.append(" AS "); - sb.append(globalState.getSchema().getFreeTableName()); - } - if (Randomly.getBoolean()) { - sb.append(" WHERE "); - sb.append(StoneDBToStringVisitor.asString(new StoneDBExpressionGenerator(globalState) - .setColumns(randomTable.getColumns()).generateExpression())); - } - if (!StoneDBBugs.bug1933 && Randomly.getBoolean()) { - sb.append(" ORDER BY "); - sb.append(String.join(", ", Randomly.fromOptions( - randomTable.getColumns().stream().map(AbstractTableColumn::getName).collect(Collectors.toList()))) - .replace('[', '(').replace(']', ')')); - } - if (Randomly.getBoolean()) { - sb.append(" LIMIT "); - sb.append(r.getInteger(0, (int) randomTable.getNrRows(globalState))); - } - addExpectedErrors(); - return new SQLQueryAdapter(sb.toString(), errors); - } - - private void addExpectedErrors() { - // java.sql.SQLException: Incorrect string value: '\xBC\xE7\xC9\x91\x05R...' for column 'c1' at row 1 - errors.add("Incorrect string value: "); - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBTableInsertGenerator.java b/src/sqlancer/stonedb/gen/StoneDBTableInsertGenerator.java deleted file mode 100644 index 0a70c8467..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBTableInsertGenerator.java +++ /dev/null @@ -1,142 +0,0 @@ -package sqlancer.stonedb.gen; - -import static sqlancer.stonedb.StoneDBBugs.bugNotReported4; -import static sqlancer.stonedb.StoneDBBugs.bugNotReported5; - -import java.util.List; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import sqlancer.Randomly; -import sqlancer.common.gen.AbstractInsertGenerator; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.common.schema.AbstractTableColumn; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.StoneDBToStringVisitor; - -public class StoneDBTableInsertGenerator extends AbstractInsertGenerator { - private final StoneDBGlobalState globalState; - // which table to insert into - private final StoneDBTable table; - // which subset columns of the table to add values - private final List columns; - ExpectedErrors errors = new ExpectedErrors(); - - public StoneDBTableInsertGenerator(StoneDBGlobalState globalState) { - this.globalState = globalState; - table = globalState.getSchema().getRandomTable(); - columns = table.getRandomNonEmptyColumnSubset(); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState) { - return new StoneDBTableInsertGenerator(globalState).getQuery(); - } - - private SQLQueryAdapter getQuery() { - sb.append("INSERT"); - if (Randomly.getBoolean()) { - sb.append(" "); - sb.append(Randomly.fromOptions("LOW_PRIORITY", "DELAYED", "HIGH_PRIORITY")); - } - if (!bugNotReported4 && Randomly.getBoolean()) { - sb.append(" IGNORE"); - } - sb.append(" INTO "); - sb.append(table.getName()); - appendPartition(); - appendColumnsAndValues(columns); - appendAS(); - appendOnDuplicateUpdate(); - addExpectedErrors(); - return new SQLQueryAdapter(sb.toString(), errors); - } - - private void addExpectedErrors() { - // java.sql.SQLException: Incorrect DATE value: '292278994-08-17' - errors.add("Incorrect DATE value: '"); - // java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1970-01-14' for key 'PRIMARY' - errors.add("Duplicate entry "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Out of range value for column 'c0' at row - errors.add("Data truncation: Out of range value for column "); - // java.sql.SQLSyntaxErrorException: Unknown column 'c0' in 'field list' - errors.add("Unknown column "); - // java.sql.SQLException: Insert duplicate key on row: 4, pk: 138609795916627968 - errors.add("Insert duplicate key on row: "); - // com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect datetime value: - errors.add("Data truncation: Incorrect datetime value: "); - // java.sql.SQLException: Field 'c0' doesn't have a default value - errors.add("doesn't have a default value"); - // java.sql.SQLException: Data truncated for column 'c0' at row 1 - errors.addRegex(Pattern.compile("Data truncated for column 'c.*' at row .*")); - } - - private void appendPartition() { - - } - - private void appendColumnsAndValues(List columns) { - sb.append("("); - sb.append(columns.stream().map(AbstractTableColumn::getName).collect(Collectors.joining(", "))); - sb.append(")"); - sb.append(Randomly.fromOptions(" VALUES ", " VALUE ")); - appendValues(); - } - - private void appendAS() { - if (!globalState.getDbmsSpecificOptions().test80Version) { - return; - } - sb.append(" AS "); - sb.append("r").append(table.getNrRows(globalState)); - } - - private void appendOnDuplicateUpdate() { - sb.append("on duplicate key update "); - StoneDBColumn randomColumn = table.getRandomColumn(); - sb.append(randomColumn.getName()); - sb.append("="); - insertValue(randomColumn); - } - - // append nrRows rows - private void appendValues() { - int nrRows; - if (Randomly.getBoolean()) { - nrRows = 1; - } else { - nrRows = 1 + Randomly.smallNumber(); - } - for (int row = 0; row < nrRows; row++) { - appendOneValue(row); - } - } - - // append all columns of one row - private void appendOneValue(int nrRow) { - if (nrRow != 0) { - sb.append(", "); - } - sb.append("("); - for (int c = 0; c < columns.size(); c++) { - if (c != 0) { - sb.append(", "); - } - insertValue(columns.get(c)); - } - sb.append(")"); - } - - // append one column of one row - @Override - protected void insertValue(StoneDBColumn column) { - if (!bugNotReported5 && Randomly.getBooleanWithRatherLowProbability()) { - sb.append("DEFAULT"); - } else { - sb.append(StoneDBToStringVisitor.asString(new StoneDBExpressionGenerator(globalState) - .generateConstant(column.getType().getPrimitiveDataType(), column.isNullable()))); - } - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBTableUpdateGenerator.java b/src/sqlancer/stonedb/gen/StoneDBTableUpdateGenerator.java deleted file mode 100644 index 259136135..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBTableUpdateGenerator.java +++ /dev/null @@ -1,71 +0,0 @@ -package sqlancer.stonedb.gen; - -import sqlancer.Randomly; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.StoneDBToStringVisitor; - -public class StoneDBTableUpdateGenerator { - private final StoneDBGlobalState globalState; - // which table to insert into - private final StoneDBTable table; - private final StringBuilder sb = new StringBuilder(); - ExpectedErrors errors = new ExpectedErrors(); - - public StoneDBTableUpdateGenerator(StoneDBGlobalState globalState) { - this.globalState = globalState; - table = globalState.getSchema().getRandomTable(); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState) { - return new StoneDBTableUpdateGenerator(globalState).getQuery(); - } - - public SQLQueryAdapter getQuery() { - sb.append("UPDATE"); - sb.append(Randomly.fromOptions(" ", " LOW_PRIORITY ", " LOW_PRIORITY IGNORE ", " IGNORE ")); - sb.append(table.getName()); - sb.append("SET "); - appendAssignmentList(); - if (Randomly.getBoolean()) { - appendWhereCondition(); - } - if (Randomly.getBoolean()) { - appendOrderBy(); - } - if (Randomly.getBoolean()) { - appendLimit(); - } - return new SQLQueryAdapter(sb.toString(), errors); - } - - public void appendAssignmentList() { - for (int i = 0; i < new Randomly().getInteger(1, table.getColumns().size()); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(table.getColumns().get(i)); - sb.append(" = "); - sb.append(Randomly.fromOptions( - StoneDBToStringVisitor.asString(StoneDBSchema.StoneDBDataType.getRandomValue( - table.getColumns().get(i).getType().getPrimitiveDataType(), globalState.getRandomly())), - "DEFAULT")); - } - } - - private void appendWhereCondition() { - } - - private void appendOrderBy() { - sb.append(" ORDER BY "); - sb.append(table.getRandomColumn().getName()); - } - - private void appendLimit() { - sb.append(" LIMIT "); - sb.append(new Randomly().getInteger(0, (int) table.getNrRows(globalState))); - } -} diff --git a/src/sqlancer/stonedb/gen/StoneDBViewCreateGenerator.java b/src/sqlancer/stonedb/gen/StoneDBViewCreateGenerator.java deleted file mode 100644 index d4ada0332..000000000 --- a/src/sqlancer/stonedb/gen/StoneDBViewCreateGenerator.java +++ /dev/null @@ -1,78 +0,0 @@ -package sqlancer.stonedb.gen; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import sqlancer.Randomly; -import sqlancer.common.ast.newast.ColumnReferenceNode; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.ast.newast.TableReferenceNode; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.StoneDBSchema.StoneDBTables; -import sqlancer.stonedb.StoneDBToStringVisitor; -import sqlancer.stonedb.ast.StoneDBExpression; -import sqlancer.stonedb.ast.StoneDBJoin; -import sqlancer.stonedb.ast.StoneDBSelect; - -public class StoneDBViewCreateGenerator { - // the name of the view to create - private final String viewName; - private final StoneDBGlobalState globalState; - private StoneDBSelect select; - private final StringBuilder sb = new StringBuilder(); - - public StoneDBViewCreateGenerator(StoneDBGlobalState globalState, String viewName) { - this.globalState = globalState; - this.viewName = viewName; - setSelect(); - } - - public static SQLQueryAdapter generate(StoneDBGlobalState globalState, String viewName) { - return new StoneDBViewCreateGenerator(globalState, viewName).getQuery(); - } - - private SQLQueryAdapter getQuery() { - sb.append("CREATE "); - sb.append("VIEW "); - sb.append(viewName); - sb.append(" AS "); - sb.append(StoneDBToStringVisitor.asString(select)); - return new SQLQueryAdapter(sb.toString(), true); - } - - private void setSelect() { - StoneDBSchema schema = globalState.getSchema(); - StoneDBTables targetTables = schema.getRandomTableNonEmptyTables(); - StoneDBExpressionGenerator gen = new StoneDBExpressionGenerator(globalState) - .setColumns(targetTables.getColumns()); - - select = new StoneDBSelect(); - select.setFetchColumns(generateFetchColumns(targetTables)); - List tables = targetTables.getTables(); - List> tableReferenceNodeList = tables.stream() - .map(t -> new TableReferenceNode(t)).collect(Collectors.toList()); - List> joins = StoneDBJoin.getJoins(tableReferenceNodeList, globalState); - select.setJoinList(new ArrayList<>(joins)); - select.setFromList(new ArrayList<>(tableReferenceNodeList)); - select.setWhereClause(gen.generateExpression()); - select.setOrderByClauses(gen.generateOrderBys()); - select.setGroupByExpressions(gen.generateExpressions(Randomly.smallNumber() + 1)); - } - - private List> generateFetchColumns(StoneDBTables tables) { - List> columns = new ArrayList<>(); - if (Randomly.getBoolean()) { - columns.add(new ColumnReferenceNode<>(new StoneDBColumn("*", null, false, false, 0))); - } else { - columns = Randomly.nonEmptySubset(tables.getColumns()).stream() - .map(c -> new ColumnReferenceNode(c)) - .collect(Collectors.toList()); - } - return columns; - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBAggregateOracle.java b/src/sqlancer/stonedb/oracle/StoneDBAggregateOracle.java deleted file mode 100644 index eb1482d7f..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBAggregateOracle.java +++ /dev/null @@ -1,170 +0,0 @@ -package sqlancer.stonedb.oracle; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import sqlancer.ComparatorHelper; -import sqlancer.IgnoreMeException; -import sqlancer.Randomly; -import sqlancer.common.ast.newast.NewAliasNode; -import sqlancer.common.ast.newast.NewFunctionNode; -import sqlancer.common.ast.newast.NewUnaryPostfixOperatorNode; -import sqlancer.common.ast.newast.NewUnaryPrefixOperatorNode; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.common.query.SQLancerResultSet; -import sqlancer.stonedb.StoneDBErrors; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBCompositeDataType; -import sqlancer.stonedb.StoneDBSchema.StoneDBDataType; -import sqlancer.stonedb.StoneDBToStringVisitor; -import sqlancer.stonedb.ast.StoneDBAggregate.StoneDBAggregateFunction; -import sqlancer.stonedb.ast.StoneDBExpression; -import sqlancer.stonedb.ast.StoneDBSelect; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator.StoneDBCastOperation; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator.StoneDBUnaryPostfixOperator; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator.StoneDBUnaryPrefixOperator; - -public class StoneDBAggregateOracle extends StoneDBQueryPartitioningBase { - - public StoneDBAggregateOracle(StoneDBGlobalState state) { - super(state); - StoneDBErrors.addExpectedExpressionErrors(state, errors); - } - - @Override - public void check() throws Exception { - super.check(); - - StoneDBAggregateFunction aggregateFunction = Randomly.fromOptions(StoneDBAggregateFunction.values()); - NewFunctionNode aggregate = gen - .generateAggregateAndArgs(aggregateFunction); - - List> fetchColumns = new ArrayList<>(); - fetchColumns.add(aggregate); - select.setFetchColumns(fetchColumns); - - if (Randomly.getBooleanWithRatherLowProbability()) { - select.setOrderByClauses(gen.generateOrderBys()); - } - - String originalQuery = StoneDBToStringVisitor.asString(select); - String originalResult = getAggregateResult(originalQuery); - - String metamorphicQuery = createMetamorphicUnionQuery(select, aggregate, select.getFromList()); - String metamorphicResult = getAggregateResult(metamorphicQuery); - - String line1 = "--" + originalQuery + ";"; - String line2 = "--" + originalResult + ";"; - String line3 = "--" + originalResult + ";"; - String line4 = "--" + metamorphicResult + ";"; - String output = String.join(System.lineSeparator(), line1, line2, line3, line4); - state.getState().getLocalState().log(output); - - if (originalResult == null && metamorphicResult != null - || originalResult != null && (!originalResult.contentEquals(metamorphicResult) - && !ComparatorHelper.isEqualDouble(originalResult, metamorphicResult))) { - throw new AssertionError("aggregate result mismatch!" + System.lineSeparator() + output); - } - } - - private String createMetamorphicUnionQuery(StoneDBSelect select, - NewFunctionNode aggregate, - List> from) { - String metamorphicQuery; - Node whereClause = gen.generateExpression(); - - Node negatedClause = new NewUnaryPrefixOperatorNode<>(whereClause, - StoneDBUnaryPrefixOperator.NOT); - Node notNullClause = new NewUnaryPostfixOperatorNode<>(whereClause, - StoneDBUnaryPostfixOperator.IS_NULL); - List> mappedAggregate = mapped(aggregate); - StoneDBSelect leftSelect = getSelect(mappedAggregate, from, whereClause, select.getJoinList()); - StoneDBSelect middleSelect = getSelect(mappedAggregate, from, negatedClause, select.getJoinList()); - StoneDBSelect rightSelect = getSelect(mappedAggregate, from, notNullClause, select.getJoinList()); - metamorphicQuery = "SELECT " + getOuterAggregateFunction(aggregate) + " FROM ("; - metamorphicQuery += StoneDBToStringVisitor.asString(leftSelect) + " UNION ALL " - + StoneDBToStringVisitor.asString(middleSelect) + " UNION ALL " - + StoneDBToStringVisitor.asString(rightSelect); - metamorphicQuery += ") as result"; - return metamorphicQuery; - } - - private String getAggregateResult(String queryString) throws SQLException { - String resultString; - SQLQueryAdapter q = new SQLQueryAdapter(queryString, errors); - try (SQLancerResultSet result = q.executeAndGet(state)) { - if (result == null) { - throw new IgnoreMeException(); - } - if (!result.next()) { - resultString = null; - } else { - resultString = result.getString(1); - } - return resultString; - } catch (SQLException e) { - if (!e.getMessage().contains("Not implemented type")) { - throw new AssertionError(queryString, e); - } else { - throw new IgnoreMeException(); - } - } - } - - private List> mapped( - NewFunctionNode aggregate) { - - StoneDBCastOperation count; - switch (aggregate.getFunc()) { - case COUNT: - case MAX: - case MIN: - case SUM: - return aliasArgs(List.of(aggregate)); - case AVG: - NewFunctionNode sum = new NewFunctionNode<>( - aggregate.getArgs(), StoneDBAggregateFunction.SUM); - count = new StoneDBCastOperation(new NewFunctionNode<>(aggregate.getArgs(), StoneDBAggregateFunction.COUNT), - new StoneDBCompositeDataType(StoneDBDataType.DECIMAL).getPrimitiveDataType()); - return aliasArgs(Arrays.asList(sum, count)); - default: - throw new AssertionError(aggregate.getFunc()); - } - } - - private List> aliasArgs(List> originalAggregateArgs) { - List> args = new ArrayList<>(); - int i = 0; - for (Node expr : originalAggregateArgs) { - args.add(new NewAliasNode(expr, "agg" + i++)); - } - return args; - } - - private String getOuterAggregateFunction(NewFunctionNode aggregate) { - switch (aggregate.getFunc()) { - case AVG: - return "SUM(agg0)/SUM(agg1)"; - case COUNT: - return StoneDBAggregateFunction.SUM + "(agg0)"; - default: - return aggregate.getFunc().toString() + "(agg0)"; - } - } - - private StoneDBSelect getSelect(List> aggregates, List> fromList, - Node whereClause, List> joinList) { - StoneDBSelect select = new StoneDBSelect(); - select.setFetchColumns(aggregates); - select.setFromList(fromList); - select.setWhereClause(whereClause); - select.setJoinList(joinList); - if (Randomly.getBooleanWithSmallProbability()) { - select.setGroupByExpressions(gen.generateExpressions(Randomly.smallNumber() + 1)); - } - return select; - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBFuzzOracle.java b/src/sqlancer/stonedb/oracle/StoneDBFuzzOracle.java deleted file mode 100644 index ebf1f9967..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBFuzzOracle.java +++ /dev/null @@ -1,67 +0,0 @@ -package sqlancer.stonedb.oracle; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import sqlancer.Randomly; -import sqlancer.common.ast.newast.ColumnReferenceNode; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.ast.newast.TableReferenceNode; -import sqlancer.common.oracle.TestOracle; -import sqlancer.common.query.ExpectedErrors; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.stonedb.StoneDBErrors; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.StoneDBSchema.StoneDBTables; -import sqlancer.stonedb.StoneDBToStringVisitor; -import sqlancer.stonedb.ast.StoneDBExpression; -import sqlancer.stonedb.ast.StoneDBJoin; -import sqlancer.stonedb.ast.StoneDBSelect; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator; - -public class StoneDBFuzzOracle implements TestOracle { - private final StoneDBGlobalState globalState; - private final StoneDBSchema schema; - private final ExpectedErrors errors = new ExpectedErrors(); - - public StoneDBFuzzOracle(StoneDBGlobalState globalState) { - this.globalState = globalState; - this.schema = globalState.getSchema(); - StoneDBErrors.addExpectedExpressionErrors(globalState, errors); - } - - @Override - public void check() throws Exception { - StoneDBTables randomTables = schema.getRandomTableNonEmptyTables(); - List columns = randomTables.getColumns(); - StoneDBExpressionGenerator gen = new StoneDBExpressionGenerator(globalState).setColumns(columns); - Node randomWhereCondition = gen.generateExpression(); - List tables = randomTables.getTables(); - List> tableList = tables.stream() - .map(t -> new TableReferenceNode(t)).collect(Collectors.toList()); - List> allColumns = columns.stream() - .map((c) -> new ColumnReferenceNode(c)).collect(Collectors.toList()); - List> joins = StoneDBJoin.getJoins(tableList, globalState); - - StoneDBSelect select = new StoneDBSelect(); - select.setFetchColumns( - Randomly.fromOptions(List.of(new ColumnReferenceNode<>(new StoneDBColumn("*", null, false, false, 0))), - allColumns, Randomly.subset(allColumns))); - select.setFromList(new ArrayList<>(tableList)); - select.setJoinList(joins); - select.setWhereClause(randomWhereCondition); - if (Randomly.getBooleanWithSmallProbability()) { - select.setOrderByClauses( - new StoneDBExpressionGenerator(globalState).setColumns(columns).generateOrderBys()); - } - select.setJoinList(joins); - - String queryString = StoneDBToStringVisitor.asString(select); - SQLQueryAdapter q = new SQLQueryAdapter(queryString, errors); - q.executeAndGetLogged(globalState); - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBNoRECOracle.java b/src/sqlancer/stonedb/oracle/StoneDBNoRECOracle.java deleted file mode 100644 index d6efe30d1..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBNoRECOracle.java +++ /dev/null @@ -1,134 +0,0 @@ -package sqlancer.stonedb.oracle; - -import static sqlancer.stonedb.StoneDBBugs.bug1953; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import sqlancer.IgnoreMeException; -import sqlancer.Randomly; -import sqlancer.SQLConnection; -import sqlancer.common.ast.newast.ColumnReferenceNode; -import sqlancer.common.ast.newast.NewBinaryOperatorNode; -import sqlancer.common.ast.newast.NewPostfixTextNode; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.ast.newast.TableReferenceNode; -import sqlancer.common.oracle.NoRECBase; -import sqlancer.common.oracle.TestOracle; -import sqlancer.common.query.SQLQueryAdapter; -import sqlancer.common.query.SQLancerResultSet; -import sqlancer.stonedb.StoneDBErrors; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBDataType; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.StoneDBSchema.StoneDBTables; -import sqlancer.stonedb.StoneDBToStringVisitor; -import sqlancer.stonedb.ast.StoneDBExpression; -import sqlancer.stonedb.ast.StoneDBJoin; -import sqlancer.stonedb.ast.StoneDBSelect; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator.StoneDBBinaryLogicalOperator; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator.StoneDBCastOperation; - -public class StoneDBNoRECOracle extends NoRECBase implements TestOracle { - - private final StoneDBSchema schema; - - public StoneDBNoRECOracle(StoneDBGlobalState globalState) { - super(globalState); - this.schema = globalState.getSchema(); - StoneDBErrors.addExpectedExpressionErrors(globalState, errors); - } - - @Override - public void check() throws Exception { - StoneDBTables randomTables = schema.getRandomTableNonEmptyTables(); - List columns = randomTables.getColumns(); - StoneDBExpressionGenerator gen = new StoneDBExpressionGenerator(state).setColumns(columns); - Node randomWhereCondition = gen.generateExpression(); - List tables = randomTables.getTables(); - List> tableList = tables.stream() - .map(t -> new TableReferenceNode(t)).collect(Collectors.toList()); - List> joins = StoneDBJoin.getJoins(tableList, state); - // get and check count - int secondCount = getUnoptimizedQueryCount(new ArrayList<>(tableList), randomWhereCondition, joins); - int firstCount = getOptimizedQueryCount(con, new ArrayList<>(tableList), columns, randomWhereCondition, joins); - if (firstCount == -1 || secondCount == -1) { - throw new IgnoreMeException(); - } - if (firstCount != secondCount) { - throw new AssertionError(optimizedQueryString + "; -- " + firstCount + System.lineSeparator() - + unoptimizedQueryString + " -- " + secondCount); - } - } - - private int getUnoptimizedQueryCount(List> tableList, - Node randomWhereCondition, List> joins) throws SQLException { - StoneDBSelect select = new StoneDBSelect(); - Node asText = new NewPostfixTextNode<>( - new StoneDBCastOperation( - new NewBinaryOperatorNode<>(new NewPostfixTextNode<>(randomWhereCondition, " IS NOT NULL "), - randomWhereCondition, StoneDBBinaryLogicalOperator.AND), - StoneDBDataType.INT), - " as count"); - select.setFetchColumns(List.of(asText)); - select.setFromList(tableList); - select.setJoinList(joins); - unoptimizedQueryString = "SELECT SUM(count) FROM (" + StoneDBToStringVisitor.asString(select) + ") as res;"; - if (bug1953) { - unoptimizedQueryString = "SELECT * FROM (" + StoneDBToStringVisitor.asString(select) + ") as res;"; - } - SQLQueryAdapter q = new SQLQueryAdapter(unoptimizedQueryString, errors); - SQLancerResultSet rs; - try { - rs = q.executeAndGetLogged(state); - } catch (Exception e) { - throw new AssertionError("error occurred when executing: \"" + unoptimizedQueryString + "\"", e); - } - if (rs == null) { - return -1; - } - int secondCount = 0; - if (rs.next()) { - secondCount += rs.getLong(1); - } - rs.close(); - return secondCount; - } - - private int getOptimizedQueryCount(SQLConnection con, List> tableList, - List columns, Node randomWhereCondition, - List> joins) { - StoneDBSelect select = new StoneDBSelect(); - List> allColumns = columns.stream() - .map((c) -> new ColumnReferenceNode(c)).collect(Collectors.toList()); - select.setFetchColumns(allColumns); - select.setFromList(tableList); - select.setWhereClause(randomWhereCondition); - if (Randomly.getBooleanWithSmallProbability()) { - select.setOrderByClauses(new StoneDBExpressionGenerator(state).setColumns(columns).generateOrderBys()); - } - select.setJoinList(joins); - int firstCount = 0; - try (Statement stat = con.createStatement()) { - optimizedQueryString = StoneDBToStringVisitor.asString(select); - if (options.logEachSelect()) { - logger.writeCurrent(optimizedQueryString); - } - try (ResultSet rs = stat.executeQuery(optimizedQueryString)) { - while (rs.next()) { - firstCount++; - } - } - } catch (SQLException e) { - throw new IgnoreMeException(); - } - return firstCount; - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningBase.java b/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningBase.java deleted file mode 100644 index 84d9f794f..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningBase.java +++ /dev/null @@ -1,71 +0,0 @@ -package sqlancer.stonedb.oracle; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import sqlancer.Randomly; -import sqlancer.common.ast.newast.ColumnReferenceNode; -import sqlancer.common.ast.newast.Node; -import sqlancer.common.ast.newast.TableReferenceNode; -import sqlancer.common.gen.ExpressionGenerator; -import sqlancer.common.oracle.TernaryLogicPartitioningOracleBase; -import sqlancer.common.oracle.TestOracle; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBSchema.StoneDBTable; -import sqlancer.stonedb.StoneDBSchema.StoneDBTables; -import sqlancer.stonedb.ast.StoneDBExpression; -import sqlancer.stonedb.ast.StoneDBJoin; -import sqlancer.stonedb.ast.StoneDBSelect; -import sqlancer.stonedb.gen.StoneDBExpressionGenerator; - -public class StoneDBQueryPartitioningBase - extends TernaryLogicPartitioningOracleBase, StoneDBGlobalState> - implements TestOracle { - - StoneDBSchema schema; - StoneDBTables targetTables; - StoneDBExpressionGenerator gen; - StoneDBSelect select; - - public StoneDBQueryPartitioningBase(StoneDBGlobalState state) { - super(state); - } - - @Override - public void check() throws Exception { - schema = state.getSchema(); - targetTables = schema.getRandomTableNonEmptyTables(); - gen = new StoneDBExpressionGenerator(state).setColumns(targetTables.getColumns()); - initializeTernaryPredicateVariants(); - - select = new StoneDBSelect(); - select.setFetchColumns(generateFetchColumns()); - List tables = targetTables.getTables(); - List> tableReferenceNodeList = tables.stream() - .map(t -> new TableReferenceNode(t)).collect(Collectors.toList()); - List> joins = StoneDBJoin.getJoins(tableReferenceNodeList, state); - select.setJoinList(new ArrayList<>(joins)); - select.setFromList(new ArrayList<>(tableReferenceNodeList)); - select.setWhereClause(null); - } - - List> generateFetchColumns() { - List> columns = new ArrayList<>(); - if (Randomly.getBoolean()) { - columns.add(new ColumnReferenceNode<>(new StoneDBColumn("*", null, false, false, 0))); - } else { - columns = Randomly.nonEmptySubset(targetTables.getColumns()).stream() - .map(c -> new ColumnReferenceNode(c)) - .collect(Collectors.toList()); - } - return columns; - } - - @Override - protected ExpressionGenerator> getGen() { - return gen; - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningDistinctTester.java b/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningDistinctTester.java deleted file mode 100644 index cba8290b4..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningDistinctTester.java +++ /dev/null @@ -1,42 +0,0 @@ -package sqlancer.stonedb.oracle; - -import java.util.ArrayList; -import java.util.List; - -import sqlancer.ComparatorHelper; -import sqlancer.Randomly; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBToStringVisitor; - -public class StoneDBQueryPartitioningDistinctTester extends StoneDBQueryPartitioningBase { - public StoneDBQueryPartitioningDistinctTester(StoneDBGlobalState state) { - super(state); - } - - @Override - public void check() throws Exception { - super.check(); - - select.setDistinct(true); - select.setWhereClause(null); - String originalQueryString = StoneDBToStringVisitor.asString(select); - List resultSet = ComparatorHelper.getResultSetFirstColumnAsString(originalQueryString, errors, state); - - if (Randomly.getBoolean()) { - select.setDistinct(false); - } - - select.setWhereClause(predicate); - String firstQueryString = StoneDBToStringVisitor.asString(select); - select.setWhereClause(negatedPredicate); - String secondQueryString = StoneDBToStringVisitor.asString(select); - select.setWhereClause(isNullPredicate); - String thirdQueryString = StoneDBToStringVisitor.asString(select); - List combinedString = new ArrayList<>(); - List secondResultSet = ComparatorHelper.getCombinedResultSetNoDuplicates(firstQueryString, - secondQueryString, thirdQueryString, combinedString, true, state, errors); - - ComparatorHelper.assumeResultSetsAreEqual(resultSet, secondResultSet, originalQueryString, combinedString, - state, ComparatorHelper::canonicalizeResultValue); - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningGroupByTester.java b/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningGroupByTester.java deleted file mode 100644 index d7674a71c..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningGroupByTester.java +++ /dev/null @@ -1,50 +0,0 @@ -package sqlancer.stonedb.oracle; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import sqlancer.ComparatorHelper; -import sqlancer.Randomly; -import sqlancer.common.ast.newast.ColumnReferenceNode; -import sqlancer.common.ast.newast.Node; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBSchema.StoneDBColumn; -import sqlancer.stonedb.StoneDBToStringVisitor; -import sqlancer.stonedb.ast.StoneDBExpression; - -public class StoneDBQueryPartitioningGroupByTester extends StoneDBQueryPartitioningBase { - public StoneDBQueryPartitioningGroupByTester(StoneDBGlobalState state) { - super(state); - } - - @Override - public void check() throws Exception { - super.check(); - // common to both original and combined query string - select.setGroupByExpressions(select.getFetchColumns()); - // specific to original query string - select.setWhereClause(null); - String originalQueryString = StoneDBToStringVisitor.asString(select); - List resultSet = ComparatorHelper.getResultSetFirstColumnAsString(originalQueryString, errors, state); - // specific to combined query string, will produce the same result as original query string in logic - select.setWhereClause(predicate); - String firstQueryString = StoneDBToStringVisitor.asString(select); - select.setWhereClause(negatedPredicate); - String secondQueryString = StoneDBToStringVisitor.asString(select); - select.setWhereClause(isNullPredicate); - String thirdQueryString = StoneDBToStringVisitor.asString(select); - List combinedString = new ArrayList<>(); - List secondResultSet = ComparatorHelper.getCombinedResultSetNoDuplicates(firstQueryString, - secondQueryString, thirdQueryString, combinedString, true, state, errors); - // compare the result - ComparatorHelper.assumeResultSetsAreEqual(resultSet, secondResultSet, originalQueryString, combinedString, - state, ComparatorHelper::canonicalizeResultValue); - } - - @Override - List> generateFetchColumns() { - return Randomly.nonEmptySubset(targetTables.getColumns()).stream() - .map(c -> new ColumnReferenceNode(c)).collect(Collectors.toList()); - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningHavingTester.java b/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningHavingTester.java deleted file mode 100644 index ce9dd6fc7..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningHavingTester.java +++ /dev/null @@ -1,47 +0,0 @@ -package sqlancer.stonedb.oracle; - -import java.util.ArrayList; -import java.util.List; - -import sqlancer.ComparatorHelper; -import sqlancer.Randomly; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBToStringVisitor; - -public class StoneDBQueryPartitioningHavingTester extends StoneDBQueryPartitioningBase { - public StoneDBQueryPartitioningHavingTester(StoneDBGlobalState state) { - super(state); - } - - @Override - public void check() throws Exception { - super.check(); - // common to both original and combined query string - if (Randomly.getBoolean()) { - select.setWhereClause(gen.generateExpression()); - } - boolean orderBy = Randomly.getBoolean(); - if (orderBy) { - select.setOrderByClauses(gen.generateOrderBys()); - } - select.setGroupByExpressions(gen.generateExpressions(Randomly.smallNumber() + 1)); - // specific to original query string - select.setHavingClause(null); - String originalQueryString = StoneDBToStringVisitor.asString(select); - List resultSet = ComparatorHelper.getResultSetFirstColumnAsString(originalQueryString, errors, state); - // specific to combined query string, will produce the same result as original - // query string in logic - select.setHavingClause(predicate); - String firstQueryString = StoneDBToStringVisitor.asString(select); - select.setHavingClause(negatedPredicate); - String secondQueryString = StoneDBToStringVisitor.asString(select); - select.setHavingClause(isNullPredicate); - String thirdQueryString = StoneDBToStringVisitor.asString(select); - List combinedString = new ArrayList<>(); - List secondResultSet = ComparatorHelper.getCombinedResultSet(firstQueryString, secondQueryString, - thirdQueryString, combinedString, !orderBy, state, errors); - // compare the result - ComparatorHelper.assumeResultSetsAreEqual(resultSet, secondResultSet, originalQueryString, combinedString, - state, ComparatorHelper::canonicalizeResultValue); - } -} diff --git a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningWhereTester.java b/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningWhereTester.java deleted file mode 100644 index 4c9267f68..000000000 --- a/src/sqlancer/stonedb/oracle/StoneDBQueryPartitioningWhereTester.java +++ /dev/null @@ -1,42 +0,0 @@ -package sqlancer.stonedb.oracle; - -import java.util.ArrayList; -import java.util.List; - -import sqlancer.ComparatorHelper; -import sqlancer.Randomly; -import sqlancer.stonedb.StoneDBProvider.StoneDBGlobalState; -import sqlancer.stonedb.StoneDBToStringVisitor; - -public class StoneDBQueryPartitioningWhereTester extends StoneDBQueryPartitioningBase { - public StoneDBQueryPartitioningWhereTester(StoneDBGlobalState state) { - super(state); - } - - @Override - public void check() throws Exception { - super.check(); - - select.setWhereClause(null); - String originalQueryString = StoneDBToStringVisitor.asString(select); - List resultSet = ComparatorHelper.getResultSetFirstColumnAsString(originalQueryString, errors, state); - - boolean orderBy = Randomly.getBooleanWithRatherLowProbability(); - if (orderBy) { - select.setOrderByClauses(gen.generateOrderBys()); - } - select.setWhereClause(predicate); - String firstQueryString = StoneDBToStringVisitor.asString(select); - select.setWhereClause(negatedPredicate); - String secondQueryString = StoneDBToStringVisitor.asString(select); - select.setWhereClause(isNullPredicate); - String thirdQueryString = StoneDBToStringVisitor.asString(select); - - List combinedString = new ArrayList<>(); - List secondResultSet = ComparatorHelper.getCombinedResultSet(firstQueryString, secondQueryString, - thirdQueryString, combinedString, !orderBy, state, errors); - // compare the result - ComparatorHelper.assumeResultSetsAreEqual(resultSet, secondResultSet, originalQueryString, combinedString, - state, ComparatorHelper::canonicalizeResultValue); - } -} diff --git a/test/sqlancer/dbms/TestStoneDBFuzz.java b/test/sqlancer/dbms/TestStoneDBFuzz.java deleted file mode 100644 index 2f5d52424..000000000 --- a/test/sqlancer/dbms/TestStoneDBFuzz.java +++ /dev/null @@ -1,21 +0,0 @@ -package sqlancer.dbms; - -import org.junit.jupiter.api.Test; -import sqlancer.Main; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -public class TestStoneDBFuzz { - - String stoneDBAvailable = System.getenv("STONEDB_AVAILABLE"); - boolean stoneDBIsAvailable = stoneDBAvailable != null && stoneDBAvailable.equalsIgnoreCase("true"); - - @Test - public void testStoneDB() { - assumeTrue(stoneDBIsAvailable); - assertEquals(0, Main.executeMain("--random-seed", "0", "--timeout-seconds", TestConfig.SECONDS, "--num-threads", - "1", "--num-queries", TestConfig.NUM_QUERIES, "stonedb", "--oracle", "FUZZER")); - } - -} \ No newline at end of file diff --git a/test/sqlancer/dbms/TestStoneDBNoRec.java b/test/sqlancer/dbms/TestStoneDBNoRec.java deleted file mode 100644 index 4b158f372..000000000 --- a/test/sqlancer/dbms/TestStoneDBNoRec.java +++ /dev/null @@ -1,22 +0,0 @@ -package sqlancer.dbms; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -import org.junit.jupiter.api.Test; - -import sqlancer.Main; - -public class TestStoneDBNoRec { - - String stoneDBAvailable = System.getenv("STONEDB_AVAILABLE"); - boolean stoneDBIsAvailable = stoneDBAvailable != null && stoneDBAvailable.equalsIgnoreCase("true"); - - @Test - public void testStoneDB() { - assumeTrue(stoneDBIsAvailable); - assertEquals(0, Main.executeMain("--random-seed", "0", "--timeout-seconds", TestConfig.SECONDS, "--num-threads", - "1", "--num-queries", TestConfig.NUM_QUERIES, "stonedb", "--oracle", "NoREC")); - } - -} diff --git a/test/sqlancer/dbms/TestStoneDBTLP.java b/test/sqlancer/dbms/TestStoneDBTLP.java deleted file mode 100644 index d5db5b9ab..000000000 --- a/test/sqlancer/dbms/TestStoneDBTLP.java +++ /dev/null @@ -1,21 +0,0 @@ -package sqlancer.dbms; - -import org.junit.jupiter.api.Test; -import sqlancer.Main; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - -public class TestStoneDBTLP { - - String stoneDBAvailable = System.getenv("STONEDB_AVAILABLE"); - boolean stoneDBIsAvailable = stoneDBAvailable != null && stoneDBAvailable.equalsIgnoreCase("true"); - - @Test - public void testStoneDB() { - assumeTrue(stoneDBIsAvailable); - assertEquals(0, Main.executeMain("--random-seed", "0", "--timeout-seconds", TestConfig.SECONDS, "--num-threads", - "1", "--num-queries", TestConfig.NUM_QUERIES, "stonedb", "--oracle", "QUERY_PARTITIONING")); - } - -}