Skip to content

Adding Join support #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/sqlancer/datafusion/DataFusionErrors.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static sqlancer.datafusion.DataFusionUtil.dfAssert;

import java.util.regex.Pattern;

import sqlancer.common.query.ExpectedErrors;

public final class DataFusionErrors {
Expand Down Expand Up @@ -31,12 +33,15 @@ public static void registerExpectedExecutionErrors(ExpectedErrors errors) {
/*
* Known bugs
*/
errors.add("to type Int64"); // https://github.com/apache/datafusion/issues/11252
errors.add("to type Int64"); // https://github.com/apache/datafusion/issues/11249
errors.add("bitwise"); // https://github.com/apache/datafusion/issues/11260
errors.add("NestedLoopJoinExec"); // https://github.com/apache/datafusion/issues/11269
errors.add(" Not all InterleaveExec children have a consistent hash partitioning."); // https://github.com/apache/datafusion/issues/11409
Pattern pattern = Pattern.compile("JOIN.*NULL", Pattern.CASE_INSENSITIVE);
errors.addRegex(pattern); // https://github.com/apache/datafusion/issues/11414
/*
* False positives
*/
errors.add("Cannot cast string"); // ifnull() is passed two non-compattable type and caused execution error
errors.add("Physical plan does not support logical expression AggregateFunction"); // False positive: when aggr
// is generated in where
// clause
Expand Down
76 changes: 54 additions & 22 deletions src/sqlancer/datafusion/DataFusionToStringVisitor.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package sqlancer.datafusion;

import static sqlancer.datafusion.DataFusionUtil.dfAssert;

import java.util.List;

import sqlancer.Randomly;
import sqlancer.common.ast.newast.NewToStringVisitor;
import sqlancer.common.ast.newast.Node;
import sqlancer.datafusion.ast.DataFusionConstant;
import sqlancer.datafusion.ast.DataFusionExpression;
import sqlancer.datafusion.ast.DataFusionJoin;
import sqlancer.datafusion.ast.DataFusionSelect;
import sqlancer.datafusion.ast.DataFusionSelect.DataFusionFrom;

public class DataFusionToStringVisitor extends NewToStringVisitor<DataFusionExpression> {

Expand All @@ -29,25 +32,61 @@ public void visitSpecific(Node<DataFusionExpression> expr) {
visit((DataFusionConstant) expr);
} else if (expr instanceof DataFusionSelect) {
visit((DataFusionSelect) expr);
} else if (expr instanceof DataFusionJoin) {
visit((DataFusionJoin) expr);
} else if (expr instanceof DataFusionFrom) {
visit((DataFusionFrom) expr);
} else {
throw new AssertionError(expr.getClass());
}
}

private void visit(DataFusionJoin join) {
visit(join.getLeftTable());
sb.append(" ");
sb.append(join.getJoinType());
sb.append(" ");

sb.append(" JOIN ");
visit(join.getRightTable());
if (join.getOnCondition() != null) {
sb.append(" ON ");
visit(join.getOnCondition());
private void visit(DataFusionFrom from) {
sb.append(" FROM ");

dfAssert(from.joinTypeList.size() == from.joinConditionList.size(), "Validate from");

/* e.g. from t1, t2, t3 */
if (from.joinConditionList.isEmpty()) {
visit(from.tableList);
return;
}

dfAssert(from.joinConditionList.size() == from.tableList.size() - 1, "Validate from");
/* e.g. from t1 join t2 on t1.v1=t2.v1 */
visit(from.tableList.get(0));
for (int i = 0; i < from.joinConditionList.size(); i++) {
switch (from.joinTypeList.get(i)) {
case INNER:
sb.append(Randomly.fromOptions(" JOIN ", " INNER JOIN "));
break;
case LEFT:
sb.append(Randomly.fromOptions(" LEFT JOIN ", " LEFT OUTER JOIN "));
break;
case RIGHT:
sb.append(Randomly.fromOptions(" RIGHT JOIN ", " RIGHT OUTER JOIN "));
break;
case FULL:
sb.append(Randomly.fromOptions(" FULL JOIN ", " FULL OUTER JOIN "));
break;
case CROSS:
sb.append(" CROSS JOIN ");
break;
case NATURAL:
sb.append(" NATURAL JOIN ");
break;
default:
dfAssert(false, "Unreachable");
}

visit(from.tableList.get(i + 1)); // ti

/* ON ... */
Node<DataFusionExpression> cond = from.joinConditionList.get(i);
if (cond != null) {
sb.append(" ON ");
visit(cond);
}
}

}

private void visit(DataFusionConstant constant) {
Expand All @@ -62,14 +101,7 @@ private void visit(DataFusionSelect select) {
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());
}
visit(select.from);
if (select.getWhereClause() != null) {
sb.append(" WHERE ");
visit(select.getWhereClause());
Expand Down
92 changes: 0 additions & 92 deletions src/sqlancer/datafusion/ast/DataFusionJoin.java

This file was deleted.

Loading
Loading