
sqlancer.sqlite3.oracle.tlp.SQLite3TLPHavingOracle Maven / Gradle / Ivy
package sqlancer.sqlite3.oracle.tlp;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import sqlancer.ComparatorHelper;
import sqlancer.IgnoreMeException;
import sqlancer.Randomly;
import sqlancer.common.oracle.TestOracle;
import sqlancer.common.query.ExpectedErrors;
import sqlancer.sqlite3.SQLite3Errors;
import sqlancer.sqlite3.SQLite3GlobalState;
import sqlancer.sqlite3.SQLite3Visitor;
import sqlancer.sqlite3.ast.SQLite3Expression;
import sqlancer.sqlite3.ast.SQLite3Expression.Join;
import sqlancer.sqlite3.ast.SQLite3Expression.SQLite3ColumnName;
import sqlancer.sqlite3.ast.SQLite3Expression.SQLite3PostfixUnaryOperation;
import sqlancer.sqlite3.ast.SQLite3Expression.SQLite3PostfixUnaryOperation.PostfixUnaryOperator;
import sqlancer.sqlite3.ast.SQLite3Select;
import sqlancer.sqlite3.ast.SQLite3Select.SelectType;
import sqlancer.sqlite3.ast.SQLite3UnaryOperation;
import sqlancer.sqlite3.ast.SQLite3UnaryOperation.UnaryOperator;
import sqlancer.sqlite3.gen.SQLite3Common;
import sqlancer.sqlite3.gen.SQLite3ExpressionGenerator;
import sqlancer.sqlite3.schema.SQLite3Schema;
import sqlancer.sqlite3.schema.SQLite3Schema.SQLite3Column;
import sqlancer.sqlite3.schema.SQLite3Schema.SQLite3Table;
import sqlancer.sqlite3.schema.SQLite3Schema.SQLite3Tables;
public class SQLite3TLPHavingOracle implements TestOracle {
private final SQLite3GlobalState state;
private final ExpectedErrors errors = new ExpectedErrors();
public SQLite3TLPHavingOracle(SQLite3GlobalState state) {
this.state = state;
SQLite3Errors.addExpectedExpressionErrors(errors);
errors.add("no such column"); // FIXME why?
errors.add("ON clause references tables to its right");
}
@Override
public void check() throws SQLException {
SQLite3Schema s = state.getSchema();
SQLite3Tables targetTables = s.getRandomTableNonEmptyTables();
List groupByColumns = Randomly.nonEmptySubset(targetTables.getColumns()).stream()
.map(c -> new SQLite3ColumnName(c, null)).collect(Collectors.toList());
List columns = targetTables.getColumns();
SQLite3ExpressionGenerator gen = new SQLite3ExpressionGenerator(state).setColumns(columns);
SQLite3Select select = new SQLite3Select();
select.setFetchColumns(groupByColumns);
List tables = targetTables.getTables();
List joinStatements = gen.getRandomJoinClauses(tables);
List from = SQLite3Common.getTableRefs(tables, state.getSchema());
select.setJoinClauses(joinStatements);
select.setSelectType(SelectType.ALL);
select.setFromTables(from);
// TODO order by?
select.setGroupByClause(groupByColumns);
select.setHavingClause(null);
String originalQueryString = SQLite3Visitor.asString(select);
List resultSet = ComparatorHelper.getResultSetFirstColumnAsString(originalQueryString, errors, state);
SQLite3Expression predicate = gen.getHavingClause();
select.setHavingClause(predicate);
String firstQueryString = SQLite3Visitor.asString(select);
select.setHavingClause(new SQLite3UnaryOperation(UnaryOperator.NOT, predicate));
String secondQueryString = SQLite3Visitor.asString(select);
select.setHavingClause(new SQLite3PostfixUnaryOperation(PostfixUnaryOperator.ISNULL, predicate));
String thirdQueryString = SQLite3Visitor.asString(select);
String combinedString = firstQueryString + " UNION ALL " + secondQueryString + " UNION ALL " + thirdQueryString;
if (combinedString.contains("EXIST")) {
throw new IgnoreMeException();
}
List secondResultSet = ComparatorHelper.getResultSetFirstColumnAsString(combinedString, errors, state);
if (state.getOptions().logEachSelect()) {
state.getLogger().writeCurrent(originalQueryString);
state.getLogger().writeCurrent(combinedString);
}
if (new HashSet<>(resultSet).size() != new HashSet<>(secondResultSet).size()) {
throw new AssertionError(originalQueryString + ";\n" + combinedString + ";");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy