Skip to content

Commit e5a8226

Browse files
authored
Merge pull request #984 from malwaregarry/tlp-h2
[H2] Use common TLP where oracle
2 parents a870c2c + 07b28ca commit e5a8226

9 files changed

Lines changed: 116 additions & 103 deletions

File tree

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ jobs:
294294
- name: Build SQLancer
295295
run: mvn -B package -DskipTests=true
296296
- name: Run Tests
297-
run: H2_AVAILABLE=true mvn -Dtest=TestH2 test
297+
run: mvn -Dtest=TestH2 test
298298

299299
hsqldb:
300300
name: DBMS Tests (HSQLB)

src/sqlancer/h2/H2ExpressionGenerator.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
package sqlancer.h2;
22

3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
36
import sqlancer.Randomly;
47
import sqlancer.common.ast.BinaryOperatorNode.Operator;
8+
import sqlancer.common.gen.TLPWhereGenerator;
59
import sqlancer.common.gen.UntypedExpressionGenerator;
10+
import sqlancer.common.schema.AbstractTables;
611
import sqlancer.h2.H2Provider.H2GlobalState;
712
import sqlancer.h2.H2Schema.H2Column;
813
import sqlancer.h2.H2Schema.H2CompositeDataType;
914
import sqlancer.h2.H2Schema.H2DataType;
15+
import sqlancer.h2.H2Schema.H2Table;
1016
import sqlancer.h2.ast.H2BetweenOperation;
1117
import sqlancer.h2.ast.H2BinaryOperation;
1218
import sqlancer.h2.ast.H2CaseOperation;
@@ -15,12 +21,17 @@
1521
import sqlancer.h2.ast.H2Constant;
1622
import sqlancer.h2.ast.H2Expression;
1723
import sqlancer.h2.ast.H2InOperation;
24+
import sqlancer.h2.ast.H2Join;
25+
import sqlancer.h2.ast.H2Select;
26+
import sqlancer.h2.ast.H2TableReference;
1827
import sqlancer.h2.ast.H2UnaryPostfixOperation;
1928
import sqlancer.h2.ast.H2UnaryPrefixOperation;
2029

21-
public class H2ExpressionGenerator extends UntypedExpressionGenerator<H2Expression, H2Column> {
30+
public class H2ExpressionGenerator extends UntypedExpressionGenerator<H2Expression, H2Column>
31+
implements TLPWhereGenerator<H2Select, H2Join, H2Expression, H2Table, H2Column> {
2232

2333
private final H2GlobalState globalState;
34+
private List<H2Table> tables;
2435

2536
public H2ExpressionGenerator(H2GlobalState globalState) {
2637
this.globalState = globalState;
@@ -336,4 +347,45 @@ public H2Expression isNull(H2Expression expr) {
336347
return new H2UnaryPostfixOperation(expr, H2UnaryPostfixOperator.IS_NULL);
337348
}
338349

350+
@Override
351+
public TLPWhereGenerator<H2Select, H2Join, H2Expression, H2Table, H2Column> setTablesAndColumns(
352+
AbstractTables<H2Table, H2Column> tables) {
353+
this.columns = tables.getColumns();
354+
this.tables = tables.getTables();
355+
356+
return this;
357+
}
358+
359+
@Override
360+
public H2Expression generateBooleanExpression() {
361+
return generateExpression();
362+
}
363+
364+
@Override
365+
public H2Select generateSelect() {
366+
return new H2Select();
367+
}
368+
369+
@Override
370+
public List<H2Join> getRandomJoinClauses() {
371+
List<H2TableReference> tableList = tables.stream().map(t -> new H2TableReference(t))
372+
.collect(Collectors.toList());
373+
List<H2Join> joins = H2Join.getJoins(tableList, globalState);
374+
tables = tableList.stream().map(t -> t.getTable()).collect(Collectors.toList());
375+
return joins;
376+
}
377+
378+
@Override
379+
public List<H2Expression> getTableRefs() {
380+
return tables.stream().map(t -> new H2TableReference(t)).collect(Collectors.toList());
381+
}
382+
383+
@Override
384+
public List<H2Expression> generateFetchColumns(boolean shouldCreateDummy) {
385+
if (shouldCreateDummy && Randomly.getBoolean()) {
386+
return List.of(new H2ColumnReference(new H2Column("*", null)));
387+
}
388+
return Randomly.nonEmptySubset(this.columns).stream().map(c -> new H2ColumnReference(c))
389+
.collect(Collectors.toList());
390+
}
339391
}

src/sqlancer/h2/H2QueryPartitioningBase.java

Lines changed: 0 additions & 62 deletions
This file was deleted.
Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,35 @@
11
package sqlancer.h2;
22

33
import java.sql.SQLException;
4-
import java.util.ArrayList;
5-
import java.util.List;
64

7-
import sqlancer.ComparatorHelper;
8-
import sqlancer.Randomly;
5+
import sqlancer.common.oracle.TLPWhereOracle;
6+
import sqlancer.common.oracle.TestOracle;
7+
import sqlancer.common.query.ExpectedErrors;
98
import sqlancer.h2.H2Provider.H2GlobalState;
9+
import sqlancer.h2.H2Schema.H2Column;
10+
import sqlancer.h2.H2Schema.H2Table;
11+
import sqlancer.h2.ast.H2Expression;
12+
import sqlancer.h2.ast.H2Join;
13+
import sqlancer.h2.ast.H2Select;
1014

11-
public class H2QueryPartitioningWhereTester extends H2QueryPartitioningBase {
15+
public class H2QueryPartitioningWhereTester implements TestOracle<H2GlobalState> {
16+
17+
private final TLPWhereOracle<H2Select, H2Join, H2Expression, H2Schema, H2Table, H2Column, H2GlobalState> oracle;
1218

1319
public H2QueryPartitioningWhereTester(H2GlobalState state) {
14-
super(state);
20+
H2ExpressionGenerator gen = new H2ExpressionGenerator(state);
21+
ExpectedErrors expectedErrors = ExpectedErrors.newErrors().with(H2Errors.getExpressionErrors()).build();
22+
23+
this.oracle = new TLPWhereOracle<>(state, gen, expectedErrors);
1524
}
1625

1726
@Override
1827
public void check() throws SQLException {
19-
super.check();
20-
select.setWhereClause(null);
21-
String originalQueryString = H2ToStringVisitor.asString(select);
22-
23-
List<String> resultSet = ComparatorHelper.getResultSetFirstColumnAsString(originalQueryString, errors, state);
24-
25-
boolean orderBy = Randomly.getBooleanWithRatherLowProbability();
26-
if (orderBy) {
27-
select.setOrderByClauses(gen.generateOrderBys());
28-
}
29-
select.setWhereClause(predicate);
30-
String firstQueryString = H2ToStringVisitor.asString(select);
31-
select.setWhereClause(negatedPredicate);
32-
String secondQueryString = H2ToStringVisitor.asString(select);
33-
select.setWhereClause(isNullPredicate);
34-
String thirdQueryString = H2ToStringVisitor.asString(select);
35-
List<String> combinedString = new ArrayList<>();
36-
List<String> secondResultSet = ComparatorHelper.getCombinedResultSet(firstQueryString, secondQueryString,
37-
thirdQueryString, combinedString, !orderBy, state, errors);
38-
ComparatorHelper.assumeResultSetsAreEqual(resultSet, secondResultSet, originalQueryString, combinedString,
39-
state);
28+
oracle.check();
4029
}
4130

31+
@Override
32+
public String getLastQueryString() {
33+
return oracle.getLastQueryString();
34+
}
4235
}

src/sqlancer/h2/H2RandomQuerySynthesizer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static H2Select generateSelect(H2GlobalState globalState, int nrColumns)
3232
List<H2Table> tables = targetTables.getTables();
3333
List<H2TableReference> tableList = tables.stream().map(t -> new H2TableReference(t))
3434
.collect(Collectors.toList());
35-
List<H2Expression> joins = H2Join.getJoins(tableList, globalState);
35+
List<H2Join> joins = H2Join.getJoins(tableList, globalState);
3636
select.setJoinList(joins.stream().collect(Collectors.toList()));
3737
select.setFromList(tableList.stream().collect(Collectors.toList()));
3838
if (Randomly.getBoolean()) {
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package sqlancer.h2.ast;
22

3-
public interface H2Expression {
3+
import sqlancer.common.ast.newast.Expression;
4+
import sqlancer.h2.H2Schema.H2Column;
5+
6+
public interface H2Expression extends Expression<H2Column> {
47

58
}

src/sqlancer/h2/ast/H2Join.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
import java.util.List;
55

66
import sqlancer.Randomly;
7+
import sqlancer.common.ast.newast.Join;
78
import sqlancer.h2.H2ExpressionGenerator;
89
import sqlancer.h2.H2Provider.H2GlobalState;
910
import sqlancer.h2.H2Schema.H2Column;
11+
import sqlancer.h2.H2Schema.H2Table;
1012

11-
public class H2Join implements H2Expression {
13+
public class H2Join implements H2Expression, Join<H2Expression, H2Table, H2Column> {
1214

1315
private final H2TableReference leftTable;
1416
private final H2TableReference rightTable;
1517
private final JoinType joinType;
16-
private final H2Expression onCondition;
18+
private H2Expression onCondition;
1719

1820
public enum JoinType {
1921
INNER, CROSS, NATURAL, LEFT, RIGHT;
@@ -47,8 +49,8 @@ public H2Expression getOnCondition() {
4749
return onCondition;
4850
}
4951

50-
public static List<H2Expression> getJoins(List<H2TableReference> tableList, H2GlobalState globalState) {
51-
List<H2Expression> joinExpressions = new ArrayList<>();
52+
public static List<H2Join> getJoins(List<H2TableReference> tableList, H2GlobalState globalState) {
53+
List<H2Join> joinExpressions = new ArrayList<>();
5254
while (tableList.size() >= 2 && Randomly.getBooleanWithRatherLowProbability()) {
5355
H2TableReference leftTable = tableList.remove(0);
5456
H2TableReference rightTable = tableList.remove(0);
@@ -91,8 +93,13 @@ public static H2Join createInnerJoin(H2TableReference left, H2TableReference rig
9193
return new H2Join(left, right, JoinType.INNER, predicate);
9294
}
9395

94-
public static H2Expression createNaturalJoin(H2TableReference left, H2TableReference right) {
96+
public static H2Join createNaturalJoin(H2TableReference left, H2TableReference right) {
9597
return new H2Join(left, right, JoinType.NATURAL, null);
9698
}
9799

100+
@Override
101+
public void setOnClause(H2Expression onClause) {
102+
onCondition = onClause;
103+
}
104+
98105
}

src/sqlancer/h2/ast/H2Select.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
package sqlancer.h2.ast;
22

3+
import java.util.List;
4+
import java.util.stream.Collectors;
5+
36
import sqlancer.common.ast.SelectBase;
7+
import sqlancer.common.ast.newast.Select;
8+
import sqlancer.h2.H2Schema.H2Column;
9+
import sqlancer.h2.H2Schema.H2Table;
10+
import sqlancer.h2.H2ToStringVisitor;
11+
12+
public class H2Select extends SelectBase<H2Expression>
13+
implements H2Expression, Select<H2Join, H2Expression, H2Table, H2Column> {
14+
15+
@Override
16+
public void setJoinClauses(List<H2Join> joinStatements) {
17+
List<H2Expression> expressions = joinStatements.stream().map(e -> (H2Expression) e)
18+
.collect(Collectors.toList());
19+
setJoinList(expressions);
20+
}
421

5-
public class H2Select extends SelectBase<H2Expression> implements H2Expression {
22+
@Override
23+
public List<H2Join> getJoinClauses() {
24+
return getJoinList().stream().map(e -> (H2Join) e).collect(Collectors.toList());
25+
}
626

27+
@Override
28+
public String asString() {
29+
return H2ToStringVisitor.asString(this);
30+
}
731
}

test/sqlancer/dbms/TestH2.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package sqlancer.dbms;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assumptions.assumeTrue;
54

65
import org.junit.jupiter.api.Test;
76

@@ -11,9 +10,6 @@ public class TestH2 {
1110

1211
@Test
1312
public void testH2DB() {
14-
String h2Available = System.getenv("H2_AVAILABLE");
15-
boolean h2DBIsAvailable = h2Available != null && h2Available.equalsIgnoreCase("true");
16-
assumeTrue(h2DBIsAvailable);
1713
assertEquals(0, Main.executeMain(new String[] { "--random-seed", "0", "--timeout-seconds", TestConfig.SECONDS,
1814
"--num-threads", "4", "--num-queries", TestConfig.NUM_QUERIES, "h2" }));
1915

0 commit comments

Comments
 (0)