This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY-8258
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY-8258 by this push:
new eaf593b GROOVY-8258: Implement inner join
eaf593b is described below
commit eaf593bdb1cf3ad4ff18e3384fa80a23010c9c25
Author: Daniel Sun <[email protected]>
AuthorDate: Tue Oct 6 02:21:19 2020 +0800
GROOVY-8258: Implement inner join
---
.../org/apache/groovy/linq/dsl/GinqAstBuilder.java | 46 +++++--
.../org/apache/groovy/linq/dsl/GinqBuilder.groovy | 135 +++++++++++++++++++--
.../org/apache/groovy/linq/dsl/GinqVisitor.java | 6 +-
...{WhereExpression.java => FilterExpression.java} | 18 ++-
.../linq/dsl/expression/FilterableExpression.java | 10 +-
.../groovy/linq/dsl/expression/FromExpression.java | 2 +-
...ereExpression.java => InnerJoinExpression.java} | 15 +--
.../{FromExpression.java => JoinExpression.java} | 30 ++---
.../{WhereExpression.java => OnExpression.java} | 16 +--
.../linq/dsl/expression/SimpleGinqExpression.java | 9 ++
.../linq/dsl/expression/WhereExpression.java | 10 +-
.../groovy/org/apache/groovy/linq/GinqTest.groovy | 14 +++
12 files changed, 227 insertions(+), 84 deletions(-)
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java
index c80e347..4905871 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqAstBuilder.java
@@ -18,9 +18,12 @@
*/
package org.apache.groovy.linq.dsl;
+import org.apache.groovy.linq.dsl.expression.FilterExpression;
import org.apache.groovy.linq.dsl.expression.FilterableExpression;
import org.apache.groovy.linq.dsl.expression.FromExpression;
import org.apache.groovy.linq.dsl.expression.GinqExpression;
+import org.apache.groovy.linq.dsl.expression.InnerJoinExpression;
+import org.apache.groovy.linq.dsl.expression.OnExpression;
import org.apache.groovy.linq.dsl.expression.SelectExpression;
import org.apache.groovy.linq.dsl.expression.SimpleGinqExpression;
import org.apache.groovy.linq.dsl.expression.WhereExpression;
@@ -57,14 +60,13 @@ public class GinqAstBuilder extends CodeVisitorSupport {
public void visitMethodCallExpression(MethodCallExpression call) {
super.visitMethodCallExpression(call);
final String methodName = call.getMethodAsString();
- System.out.println(methodName + " : " + call);
- if ("from".equals(methodName)) {
+ if ("from".equals(methodName) || "innerJoin".equals(methodName)) {
ArgumentListExpression arguments = (ArgumentListExpression)
call.getArguments();
if (arguments.getExpressions().size() != 1) {
this.collectSyntaxError(
new GinqSyntaxError(
- "Only 1 argument expected for `from`, e.g.
`from n in nums`",
+ "Only 1 argument expected for `" + methodName
+ "`, e.g. `" + methodName + " n in nums`",
call.getLineNumber(), call.getColumnNumber()
)
);
@@ -74,7 +76,7 @@ public class GinqAstBuilder extends CodeVisitorSupport {
&& ((BinaryExpression)
expression).getOperation().getType() == Types.KEYWORD_IN)) {
this.collectSyntaxError(
new GinqSyntaxError(
- "`in` is expected for `from`, e.g. `from n in
nums`",
+ "`in` is expected for `" + methodName + "`,
e.g. `" + methodName + " n in nums`",
call.getLineNumber(), call.getColumnNumber()
)
);
@@ -83,21 +85,39 @@ public class GinqAstBuilder extends CodeVisitorSupport {
Expression aliasExpr = binaryExpression.getLeftExpression();
Expression dataSourceExpr = binaryExpression.getRightExpression();
- FromExpression fromExpression = new FromExpression(aliasExpr,
dataSourceExpr);
- fromExpression.setSourcePosition(call);
+ if ("from".equals(methodName)) {
+ FromExpression fromExpression = new FromExpression(aliasExpr,
dataSourceExpr);
+ fromExpression.setSourcePosition(call);
+ simpleGinqExpression.addFromExpression(fromExpression);
+ ginqExpression = fromExpression;
+ } else if ("innerJoin".equals(methodName)) {
+ InnerJoinExpression innerJoinExpression = new
InnerJoinExpression(aliasExpr, dataSourceExpr);
+ innerJoinExpression.setSourcePosition(call);
+ simpleGinqExpression.addJoinExpression(innerJoinExpression);
+ ginqExpression = innerJoinExpression;
+ }
- simpleGinqExpression.addFromExpression(fromExpression);
- ginqExpression = fromExpression;
return;
}
- if ("where".equals(methodName)) {
+ if ("where".equals(methodName) || "on".equals(methodName)) {
Expression filterExpr = ((ArgumentListExpression)
call.getArguments()).getExpression(0);
- WhereExpression whereExpression = new WhereExpression(filterExpr);
- whereExpression.setSourcePosition(call);
- if (ginqExpression instanceof FilterableExpression) {
- ((FilterableExpression)
ginqExpression).setWhereExpression(whereExpression);
+ FilterExpression filterExpression = null;
+ if ("where".equals(methodName)) {
+ filterExpression = new WhereExpression(filterExpr);
+ } else if ("on".equals(methodName)) {
+ filterExpression = new OnExpression(filterExpr);
+ }
+
+ if (null == filterExpression) {
+ throw new GroovyBugError("Unknown method: " + methodName);
+ }
+
+ filterExpression.setSourcePosition(call);
+
+ if (ginqExpression instanceof FilterableExpression) { // TODO more
strict check
+ ((FilterableExpression)
ginqExpression).setFilterExpression(filterExpression);
} else {
throw new GroovyBugError("The preceding expression is not a
FilterableExpression: " + ginqExpression);
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqBuilder.groovy
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqBuilder.groovy
index 098bd41..bbfe3cb 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqBuilder.groovy
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqBuilder.groovy
@@ -22,13 +22,19 @@ import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.apache.groovy.linq.dsl.expression.FromExpression
import org.apache.groovy.linq.dsl.expression.GinqExpression
-import org.apache.groovy.linq.dsl.expression.SimpleGinqExpression
+import org.apache.groovy.linq.dsl.expression.InnerJoinExpression
+import org.apache.groovy.linq.dsl.expression.JoinExpression
+import org.apache.groovy.linq.dsl.expression.OnExpression
import org.apache.groovy.linq.dsl.expression.SelectExpression
+import org.apache.groovy.linq.dsl.expression.SimpleGinqExpression
import org.apache.groovy.linq.dsl.expression.WhereExpression
import org.codehaus.groovy.ast.ClassHelper
import org.codehaus.groovy.ast.expr.ArgumentListExpression
import org.codehaus.groovy.ast.expr.Expression
+import org.codehaus.groovy.ast.expr.ExpressionTransformer
+import org.codehaus.groovy.ast.expr.ListExpression
import org.codehaus.groovy.ast.expr.MethodCallExpression
+import org.codehaus.groovy.ast.expr.VariableExpression
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX
import static org.codehaus.groovy.ast.tools.GeneralUtils.lambdaX
@@ -43,20 +49,50 @@ import static
org.codehaus.groovy.ast.tools.GeneralUtils.stmt
*/
@CompileStatic
class GinqBuilder implements GinqVisitor<Object> {
+
+ public static final String __RECEIVER_ALIAS_EXPR = "__receiverAliasExpr"
+ public static final String __INNER_JOIN_METHOD_RECEIVER =
"__inner_join_method_receiver"
+ public static final String __T = "__t"
+ public static final String __FIRST_ALIAS_EXPR = "__first_alias_expr"
+ public static final String __SECOND_ALIAS_EXPR = "__second_alias_expr"
+
@Override
MethodCallExpression visitSimpleGinqExpression(SimpleGinqExpression
simpleGinqExpression) {
List<MethodCallExpression> fromMethodCallExpressionList = new
LinkedList<>()
List<FromExpression> fromExpressionList =
simpleGinqExpression.getFromExpressionList()
- for (FromExpression fromExpression : (fromExpressionList)) {
+ for (FromExpression fromExpression : fromExpressionList) {
MethodCallExpression methodCallExpression =
this.visitFromExpression(fromExpression)
fromMethodCallExpressionList.add(methodCallExpression)
}
MethodCallExpression selectMethodReceiver =
fromMethodCallExpressionList.getLast()
+ List<MethodCallExpression> innerJoinMethodCallExpressionList = new
LinkedList<>()
+ List<JoinExpression> joinExpressionList =
simpleGinqExpression.getJoinExpressionList()
+ for (JoinExpression joinExpression : joinExpressionList) {
+ joinExpression.putNodeMetaData(__INNER_JOIN_METHOD_RECEIVER,
fromMethodCallExpressionList.getLast())
+ joinExpression.putNodeMetaData(__RECEIVER_ALIAS_EXPR,
fromExpressionList.get(fromExpressionList.size() - 1).aliasExpr)
+ MethodCallExpression methodCallExpression =
this.visitInnerJoinExpression((InnerJoinExpression) joinExpression)
+ innerJoinMethodCallExpressionList.add(methodCallExpression);
+ }
+
+ if (innerJoinMethodCallExpressionList) {
+ selectMethodReceiver = innerJoinMethodCallExpressionList.getLast()
+ }
+
SelectExpression selectExpression =
simpleGinqExpression.getSelectExpression()
selectExpression.putNodeMetaData(__SELECT_METHOD_RECEIVER,
selectMethodReceiver)
- selectExpression.putNodeMetaData(__ALIAS_EXPR,
fromExpressionList.get(fromExpressionList.size() - 1).aliasExpr)
+
+ if (joinExpressionList) {
+ JoinExpression lastJoinExpression =
joinExpressionList.get(joinExpressionList.size() - 1)
+ selectExpression.putNodeMetaData(__FIRST_ALIAS_EXPR,
lastJoinExpression.getNodeMetaData(__RECEIVER_ALIAS_EXPR))
+ selectExpression.putNodeMetaData(__SECOND_ALIAS_EXPR,
lastJoinExpression.aliasExpr)
+
+ selectExpression.putNodeMetaData(__ALIAS_EXPR, new
VariableExpression(__T))
+ } else {
+ selectExpression.putNodeMetaData(__ALIAS_EXPR,
fromExpressionList.get(fromExpressionList.size() - 1).aliasExpr)
+ }
+
MethodCallExpression selectMethodCallExpression =
this.visitSelectExpression(selectExpression)
@@ -67,7 +103,7 @@ class GinqBuilder implements GinqVisitor<Object> {
MethodCallExpression visitFromExpression(FromExpression fromExpression) {
MethodCallExpression fromMethodCallExpression =
constructFromMethodCallExpression(fromExpression)
- WhereExpression whereExpression = fromExpression.getWhereExpression()
+ WhereExpression whereExpression = (WhereExpression)
fromExpression.getFilterExpression()
if (whereExpression) {
whereExpression.putNodeMetaData(__FROM_EXPRESSION, fromExpression)
whereExpression.putNodeMetaData(__FROM_METHOD_CALL_EXPRESSION,
fromMethodCallExpression)
@@ -78,14 +114,47 @@ class GinqBuilder implements GinqVisitor<Object> {
return fromMethodCallExpression
}
+ @Override
+ MethodCallExpression visitInnerJoinExpression(InnerJoinExpression
innerJoinExpression) {
+ Expression receiver =
innerJoinExpression.getNodeMetaData(__INNER_JOIN_METHOD_RECEIVER)
+ Expression receiverAliasExpr =
innerJoinExpression.getNodeMetaData(__RECEIVER_ALIAS_EXPR)
+ OnExpression onExpression = (OnExpression)
innerJoinExpression.getFilterExpression()
+ MethodCallExpression innerJoinMethodCallExpression =
constructInnerJoinMethodCallExpression(receiver, receiverAliasExpr,
innerJoinExpression, onExpression)
+
+ return innerJoinMethodCallExpression
+ }
+
+ @Override
+ MethodCallExpression visitOnExpression(OnExpression onExpression) {
+ return null // do nothing
+ }
+
@CompileDynamic
private MethodCallExpression
constructFromMethodCallExpression(FromExpression fromExpression) {
macro {
- org.apache.groovy.linq.provider.QueryableCollection
- .from($v { fromExpression.dataSourceExpr })
+ org.apache.groovy.linq.provider.QueryableCollection.from($v {
fromExpression.dataSourceExpr })
}
}
+ @CompileDynamic
+ private MethodCallExpression
constructInnerJoinMethodCallExpression(Expression receiver, Expression
receiverAliasExpr, InnerJoinExpression innerJoinExpression, OnExpression
onExpression) {
+ MethodCallExpression innerJoinMethodCallExpression = macro {
+
$v{receiver}.innerJoin(org.apache.groovy.linq.provider.QueryableCollection.from($v
{ innerJoinExpression.dataSourceExpr }))
+ }
+
+ ((ArgumentListExpression)
innerJoinMethodCallExpression.getArguments()).getExpressions().add(
+ lambdaX(
+ params(
+ param(ClassHelper.DYNAMIC_TYPE,
receiverAliasExpr.text),
+ param(ClassHelper.DYNAMIC_TYPE,
innerJoinExpression.aliasExpr.text)
+ ),
+ stmt(onExpression.getFilterExpr())
+ )
+ )
+
+ return innerJoinMethodCallExpression
+ }
+
@Override
MethodCallExpression visitWhereExpression(WhereExpression whereExpression)
{
FromExpression fromExpression =
whereExpression.getNodeMetaData(__FROM_EXPRESSION)
@@ -97,7 +166,59 @@ class GinqBuilder implements GinqVisitor<Object> {
MethodCallExpression visitSelectExpression(SelectExpression
selectExpression) {
Expression selectMethodReceiver =
selectExpression.getNodeMetaData(__SELECT_METHOD_RECEIVER)
Expression aliasExpr = selectExpression.getNodeMetaData(__ALIAS_EXPR)
- return callXWithLambda(selectMethodReceiver, "select", aliasExpr.text,
((ArgumentListExpression)
selectExpression.getProjectionExpr()).getExpression(0))
+ Expression projectionExpr = selectExpression.getProjectionExpr()
+
+ if (__T.equals(aliasExpr.text)) {
+ projectionExpr =
correctVariablesOfProjectExpression(selectExpression, projectionExpr)
+ }
+
+ List<Expression> expressionList = ((ArgumentListExpression)
projectionExpr).getExpressions()
+ Expression lambdaCode
+ if (expressionList.size() > 1) {
+ lambdaCode = new ListExpression(expressionList)
+ } else {
+ lambdaCode = expressionList.get(0)
+ }
+
+ return callXWithLambda(selectMethodReceiver, "select", aliasExpr.text,
lambdaCode)
+ }
+
+ private Expression correctVariablesOfProjectExpression(SelectExpression
selectExpression, Expression projectionExpr) {
+ final Expression firstAliasExpr =
selectExpression.getNodeMetaData(__FIRST_ALIAS_EXPR)
+ final Expression secondAliasExpr =
selectExpression.getNodeMetaData(__SECOND_ALIAS_EXPR)
+
+ projectionExpr = projectionExpr.transformExpression(new
ExpressionTransformer() {
+ @Override
+ Expression transform(Expression expression) {
+ if (expression instanceof VariableExpression) {
+ Expression transformedExpression = null
+ if (firstAliasExpr.text == expression.text) {
+ // replace `n1` with `__t.v1`
+ transformedExpression =
constructFirstAliasVariableAccess()
+ } else if (secondAliasExpr.text == expression.text) {
+ // replace `n2` with `__t.v2`
+ transformedExpression =
constructSecondAliasVariableAccess()
+ }
+
+ if (null != transformedExpression) {
+ return transformedExpression
+ }
+ }
+
+ return expression.transformExpression(this)
+ }
+ })
+ return projectionExpr
+ }
+
+ @CompileDynamic
+ private Expression constructFirstAliasVariableAccess() {
+ macro { __t.v1 }
+ }
+
+ @CompileDynamic
+ private Expression constructSecondAliasVariableAccess() {
+ macro { __t.v2 }
}
@Override
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqVisitor.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqVisitor.java
index 3ee3f4f..3e5f27e 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqVisitor.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/GinqVisitor.java
@@ -20,8 +20,10 @@ package org.apache.groovy.linq.dsl;
import org.apache.groovy.linq.dsl.expression.FromExpression;
import org.apache.groovy.linq.dsl.expression.GinqExpression;
-import org.apache.groovy.linq.dsl.expression.SimpleGinqExpression;
+import org.apache.groovy.linq.dsl.expression.InnerJoinExpression;
+import org.apache.groovy.linq.dsl.expression.OnExpression;
import org.apache.groovy.linq.dsl.expression.SelectExpression;
+import org.apache.groovy.linq.dsl.expression.SimpleGinqExpression;
import org.apache.groovy.linq.dsl.expression.WhereExpression;
/**
@@ -33,6 +35,8 @@ import org.apache.groovy.linq.dsl.expression.WhereExpression;
public interface GinqVisitor<R> {
R visitSimpleGinqExpression(SimpleGinqExpression simpleGinqExpression);
R visitFromExpression(FromExpression fromExpression);
+ R visitInnerJoinExpression(InnerJoinExpression innerJoinExpression);
+ R visitOnExpression(OnExpression onExpression);
R visitWhereExpression(WhereExpression whereExpression);
R visitSelectExpression(SelectExpression selectExpression);
R visit(GinqExpression expression);
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FilterExpression.java
similarity index 75%
copy from
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
copy to
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FilterExpression.java
index 052347d..0fb4dde 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FilterExpression.java
@@ -18,27 +18,25 @@
*/
package org.apache.groovy.linq.dsl.expression;
-import org.apache.groovy.linq.dsl.GinqVisitor;
import org.codehaus.groovy.ast.expr.Expression;
/**
- * Represent the where expression
+ * Represents filter expression
*
* @since 4.0.0
*/
-public class WhereExpression extends AbstractGinqExpression {
- private final Expression filterExpr;
+public abstract class FilterExpression extends AbstractGinqExpression {
+ protected Expression filterExpr;
- public WhereExpression(Expression filterExpr) {
+ public FilterExpression(Expression filterExpr) {
this.filterExpr = filterExpr;
}
- @Override
- public <R> R accept(GinqVisitor<R> visitor) {
- return visitor.visitWhereExpression(this);
- }
-
public Expression getFilterExpr() {
return filterExpr;
}
+
+ public void setFilterExpr(Expression filterExpr) {
+ this.filterExpr = filterExpr;
+ }
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FilterableExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FilterableExpression.java
index c0c1e8f..3ce3523 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FilterableExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FilterableExpression.java
@@ -24,13 +24,13 @@ package org.apache.groovy.linq.dsl.expression;
* @since 4.0.0
*/
public abstract class FilterableExpression extends AbstractGinqExpression {
- protected WhereExpression whereExpression;
+ protected FilterExpression filterExpression;
- public WhereExpression getWhereExpression() {
- return whereExpression;
+ public FilterExpression getFilterExpression() {
+ return filterExpression;
}
- public void setWhereExpression(WhereExpression whereExpression) {
- this.whereExpression = whereExpression;
+ public void setFilterExpression(FilterExpression filterExpression) {
+ this.filterExpression = filterExpression;
}
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
index 248e9c0..b880cf8 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
@@ -53,7 +53,7 @@ public class FromExpression extends FilterableExpression {
return "FromExpression{" +
"aliasExpr=" + aliasExpr +
", dataSourceExpr=" + dataSourceExpr +
- ", whereExpression=" + whereExpression +
+ ", whereExpression=" + filterExpression +
'}';
}
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/InnerJoinExpression.java
similarity index 75%
copy from
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
copy to
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/InnerJoinExpression.java
index 052347d..8df0377 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/InnerJoinExpression.java
@@ -22,23 +22,18 @@ import org.apache.groovy.linq.dsl.GinqVisitor;
import org.codehaus.groovy.ast.expr.Expression;
/**
- * Represent the where expression
+ * Represents inner join expression
*
* @since 4.0.0
*/
-public class WhereExpression extends AbstractGinqExpression {
- private final Expression filterExpr;
+public class InnerJoinExpression extends JoinExpression {
- public WhereExpression(Expression filterExpr) {
- this.filterExpr = filterExpr;
+ public InnerJoinExpression(Expression aliasExpr, Expression
dataSourceExpr) {
+ super(aliasExpr, dataSourceExpr);
}
@Override
public <R> R accept(GinqVisitor<R> visitor) {
- return visitor.visitWhereExpression(this);
- }
-
- public Expression getFilterExpr() {
- return filterExpr;
+ return visitor.visitInnerJoinExpression(this);
}
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/JoinExpression.java
similarity index 64%
copy from
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
copy to
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/JoinExpression.java
index 248e9c0..85debc4 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/FromExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/JoinExpression.java
@@ -18,26 +18,29 @@
*/
package org.apache.groovy.linq.dsl.expression;
-import org.apache.groovy.linq.dsl.GinqVisitor;
import org.codehaus.groovy.ast.expr.Expression;
/**
- * Represents the from expression
+ * Represents join expression
*
* @since 4.0.0
*/
-public class FromExpression extends FilterableExpression {
- private final Expression aliasExpr;
- private final Expression dataSourceExpr;
+public abstract class JoinExpression extends FilterableExpression {
+ protected OnExpression onExpression;
+ protected Expression aliasExpr;
+ protected Expression dataSourceExpr;
- public FromExpression(Expression aliasExpr, Expression dataSourceExpr) {
+ public JoinExpression(Expression aliasExpr, Expression dataSourceExpr) {
this.aliasExpr = aliasExpr;
this.dataSourceExpr = dataSourceExpr;
}
- @Override
- public <R> R accept(GinqVisitor<R> visitor) {
- return visitor.visitFromExpression(this);
+ public OnExpression getOnExpression() {
+ return onExpression;
+ }
+
+ public void setOnExpression(OnExpression onExpression) {
+ this.onExpression = onExpression;
}
public Expression getAliasExpr() {
@@ -47,13 +50,4 @@ public class FromExpression extends FilterableExpression {
public Expression getDataSourceExpr() {
return dataSourceExpr;
}
-
- @Override
- public String toString() {
- return "FromExpression{" +
- "aliasExpr=" + aliasExpr +
- ", dataSourceExpr=" + dataSourceExpr +
- ", whereExpression=" + whereExpression +
- '}';
- }
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/OnExpression.java
similarity index 75%
copy from
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
copy to
subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/OnExpression.java
index 052347d..98394d7 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/OnExpression.java
@@ -22,23 +22,17 @@ import org.apache.groovy.linq.dsl.GinqVisitor;
import org.codehaus.groovy.ast.expr.Expression;
/**
- * Represent the where expression
+ * Represents on expression
*
* @since 4.0.0
*/
-public class WhereExpression extends AbstractGinqExpression {
- private final Expression filterExpr;
-
- public WhereExpression(Expression filterExpr) {
- this.filterExpr = filterExpr;
+public class OnExpression extends FilterExpression {
+ public OnExpression(Expression filterExpr) {
+ super(filterExpr);
}
@Override
public <R> R accept(GinqVisitor<R> visitor) {
- return visitor.visitWhereExpression(this);
- }
-
- public Expression getFilterExpr() {
- return filterExpr;
+ return visitor.visitOnExpression(this);
}
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/SimpleGinqExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/SimpleGinqExpression.java
index 21c00f4..23d59ed 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/SimpleGinqExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/SimpleGinqExpression.java
@@ -30,6 +30,7 @@ import java.util.List;
*/
public class SimpleGinqExpression extends AbstractGinqExpression {
private final List<FromExpression> fromExpressionList = new ArrayList<>();
+ private final List<JoinExpression> joinExpressionList = new ArrayList<>();
private SelectExpression selectExpression;
@Override
@@ -45,6 +46,14 @@ public class SimpleGinqExpression extends
AbstractGinqExpression {
this.fromExpressionList.add(fromExpression);
}
+ public List<JoinExpression> getJoinExpressionList() {
+ return joinExpressionList;
+ }
+
+ public void addJoinExpression(JoinExpression joinExpression) {
+ joinExpressionList.add(joinExpression);
+ }
+
public SelectExpression getSelectExpression() {
return selectExpression;
}
diff --git
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
index 052347d..66bde4f 100644
---
a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
+++
b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/dsl/expression/WhereExpression.java
@@ -26,19 +26,13 @@ import org.codehaus.groovy.ast.expr.Expression;
*
* @since 4.0.0
*/
-public class WhereExpression extends AbstractGinqExpression {
- private final Expression filterExpr;
-
+public class WhereExpression extends FilterExpression {
public WhereExpression(Expression filterExpr) {
- this.filterExpr = filterExpr;
+ super(filterExpr);
}
@Override
public <R> R accept(GinqVisitor<R> visitor) {
return visitor.visitWhereExpression(this);
}
-
- public Expression getFilterExpr() {
- return filterExpr;
- }
}
diff --git
a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
index 1cdb0ef..96d04cb 100644
---
a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
+++
b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
@@ -60,4 +60,18 @@ class GinqTest {
}.toList()
'''
}
+
+ @Test
+ void "testGinq - from innerJoin select"() {
+ assertScript '''
+ def nums1 = [1, 2, 3]
+ def nums2 = [1, 2, 3]
+ assert [[1, 1], [2, 2], [3, 3]] == GINQ {
+ from n1 in nums1
+ innerJoin n2 in nums2
+ on n1 == n2
+ select n1, n2
+ }.toList()
+ '''
+ }
}