You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/02/16 12:56:14 UTC
cayenne git commit: CAY-2231 Support for collections in new
functional expressions and old math expressions
Repository: cayenne
Updated Branches:
refs/heads/master 5c805019a -> 2667f0126
CAY-2231 Support for collections in new functional expressions and old math expressions
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/2667f012
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/2667f012
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/2667f012
Branch: refs/heads/master
Commit: 2667f0126a6a2a3abafbb174898998aae66e8a80
Parents: 5c80501
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Feb 16 15:49:52 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Feb 16 15:49:52 2017 +0300
----------------------------------------------------------------------
.../org/apache/cayenne/exp/parser/ASTAbs.java | 9 +-
.../org/apache/cayenne/exp/parser/ASTAdd.java | 33 +----
.../exp/parser/ASTAggregateFunctionCall.java | 7 +-
.../cayenne/exp/parser/ASTBitwiseAnd.java | 34 ++----
.../cayenne/exp/parser/ASTBitwiseLeftShift.java | 34 ++----
.../cayenne/exp/parser/ASTBitwiseNot.java | 18 ++-
.../apache/cayenne/exp/parser/ASTBitwiseOr.java | 39 ++----
.../exp/parser/ASTBitwiseRightShift.java | 34 +-----
.../cayenne/exp/parser/ASTBitwiseXor.java | 37 ++----
.../apache/cayenne/exp/parser/ASTConcat.java | 12 +-
.../cayenne/exp/parser/ASTCurrentDate.java | 7 +-
.../cayenne/exp/parser/ASTCurrentTime.java | 7 +-
.../cayenne/exp/parser/ASTCurrentTimestamp.java | 7 +-
.../apache/cayenne/exp/parser/ASTDivide.java | 32 +----
.../cayenne/exp/parser/ASTFunctionCall.java | 2 +-
.../apache/cayenne/exp/parser/ASTLength.java | 9 +-
.../apache/cayenne/exp/parser/ASTLocate.java | 21 ++--
.../org/apache/cayenne/exp/parser/ASTLower.java | 9 +-
.../org/apache/cayenne/exp/parser/ASTMod.java | 10 ++
.../apache/cayenne/exp/parser/ASTMultiply.java | 32 +----
.../org/apache/cayenne/exp/parser/ASTSqrt.java | 9 +-
.../apache/cayenne/exp/parser/ASTSubstring.java | 22 ++--
.../apache/cayenne/exp/parser/ASTSubtract.java | 31 +----
.../org/apache/cayenne/exp/parser/ASTTrim.java | 10 +-
.../org/apache/cayenne/exp/parser/ASTUpper.java | 9 +-
.../exp/parser/EvaluatedBitwiseNode.java | 57 +++++++++
.../cayenne/exp/parser/EvaluatedMathNode.java | 58 +++++++++
.../cayenne/exp/parser/EvaluatedNode.java | 85 +++++++++++++
.../exp/parser/ASTFunctionCallStringIT.java | 2 +-
.../cayenne/exp/parser/ASTSubstringTest.java | 2 +-
.../ExpressionCollectionEvaluationIT.java | 122 +++++++++++++++++++
docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 +
32 files changed, 497 insertions(+), 304 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAbs.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAbs.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAbs.java
index b5220bb..e49972c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAbs.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAbs.java
@@ -36,12 +36,17 @@ public class ASTAbs extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- double n = ConversionUtil.toDouble(evaluateChild(0, o), 0.0);
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ double n = ConversionUtil.toDouble(o, 0.0);
return Math.abs(n);
}
@Override
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
public Expression shallowCopy() {
return new ASTAbs(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
index de484ef..8554bdc 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAdd.java
@@ -20,16 +20,16 @@
package org.apache.cayenne.exp.parser;
import java.math.BigDecimal;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
* "Add" Expression.
*/
-public class ASTAdd extends SimpleNode {
+public class ASTAdd extends EvaluatedMathNode {
private static final long serialVersionUID = -8622963819149351988L;
@@ -42,13 +42,7 @@ public class ASTAdd extends SimpleNode {
}
public ASTAdd(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTADD);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTAdd(Collection<?> nodes) {
@@ -58,29 +52,12 @@ public class ASTAdd extends SimpleNode {
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
-
connectChildren();
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- BigDecimal result = null;
- for (int i = 0; i < len; i++) {
- BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
-
- if (value == null) {
- return null;
- }
-
- result = (i == 0) ? value : result.add(value);
- }
-
- return result;
+ protected BigDecimal op(BigDecimal result, BigDecimal arg) {
+ return result.add(arg);
}
/**
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAggregateFunctionCall.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAggregateFunctionCall.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAggregateFunctionCall.java
index 641f711..626edf8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAggregateFunctionCall.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTAggregateFunctionCall.java
@@ -35,7 +35,12 @@ public abstract class ASTAggregateFunctionCall extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
+ protected int getRequiredChildrenCount() {
+ return 0;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
throw new UnsupportedOperationException("In-memory evaluation of aggregate functions not implemented yet.");
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
index 9fe8a2f..10fd9a5 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseAnd.java
@@ -18,18 +18,18 @@
****************************************************************/
package org.apache.cayenne.exp.parser;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
* Bitwise conjunction (AND or '&') expression
*
* @since 3.1
*/
-public class ASTBitwiseAnd extends SimpleNode {
+public class ASTBitwiseAnd extends EvaluatedBitwiseNode {
private static final long serialVersionUID = -1482206814209874743L;
@@ -42,13 +42,7 @@ public class ASTBitwiseAnd extends SimpleNode {
}
public ASTBitwiseAnd(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTBITWISEAND);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTBitwiseAnd(Collection<Object> nodes) {
@@ -58,27 +52,13 @@ public class ASTBitwiseAnd extends SimpleNode {
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
+
+ connectChildren();
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- Long result = null;
- for (int i = 0; i < len; i++) {
- Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
-
- if (value == Long.MIN_VALUE) {
- return null;
- }
-
- result = (i == 0) ? value : result & value;
- }
-
- return result;
+ protected long op(long result, long arg) {
+ return result & arg;
}
@Override
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
index d7c8606..2410129 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseLeftShift.java
@@ -18,18 +18,18 @@
****************************************************************/
package org.apache.cayenne.exp.parser;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
* Bitwise left shift '<<' operation.
*
* @since 4.0
*/
-public class ASTBitwiseLeftShift extends SimpleNode {
+public class ASTBitwiseLeftShift extends EvaluatedBitwiseNode {
private static final long serialVersionUID = -954784931828996446L;
@@ -42,13 +42,7 @@ public class ASTBitwiseLeftShift extends SimpleNode {
}
public ASTBitwiseLeftShift(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTBITWISELEFTSHIFT);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTBitwiseLeftShift(Collection<Object> nodes) {
@@ -58,27 +52,13 @@ public class ASTBitwiseLeftShift extends SimpleNode {
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
+
+ connectChildren();
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- Long result = null;
- for (int i = 0; i < len; i++) {
- Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
-
- if (value == Long.MIN_VALUE) {
- return null;
- }
-
- result = (i == 0) ? value : result << value;
- }
-
- return result;
+ protected long op(long result, long arg) {
+ return result << arg;
}
@Override
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java
index a86761f..50a970e 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseNot.java
@@ -26,7 +26,7 @@ import org.apache.cayenne.util.ConversionUtil;
*
* @since 3.1
*/
-public class ASTBitwiseNot extends SimpleNode {
+public class ASTBitwiseNot extends EvaluatedNode {
private static final long serialVersionUID = 1L;
ASTBitwiseNot(int id) {
@@ -44,21 +44,17 @@ public class ASTBitwiseNot extends SimpleNode {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
-
- int len = jjtGetNumChildren();
- if (len != 1) {
- return Boolean.FALSE;
- }
-
- long value = ConversionUtil.toLong(evaluateChild(0, o), Long.MIN_VALUE);
-
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ long value = ConversionUtil.toLong(o, Long.MIN_VALUE);
if (value == Long.MIN_VALUE) {
return null;
}
-
return ~value;
+ }
+ @Override
+ protected int getRequiredChildrenCount() {
+ return 1;
}
@Override
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java
index 8b3060c..87ad19d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseOr.java
@@ -18,11 +18,11 @@
****************************************************************/
package org.apache.cayenne.exp.parser;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
@@ -30,7 +30,7 @@ import org.apache.cayenne.util.ConversionUtil;
*
* @since 3.1
*/
-public class ASTBitwiseOr extends SimpleNode {
+public class ASTBitwiseOr extends EvaluatedBitwiseNode {
private static final long serialVersionUID = 1L;
ASTBitwiseOr(int id) {
@@ -42,13 +42,7 @@ public class ASTBitwiseOr extends SimpleNode {
}
public ASTBitwiseOr(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTBITWISEOR);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTBitwiseOr(Collection<Object> nodes) {
@@ -58,30 +52,15 @@ public class ASTBitwiseOr extends SimpleNode {
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
+ connectChildren();
}
-
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- Long result = null;
- for (int i = 0; i < len; i++) {
- Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
-
- if (value == Long.MIN_VALUE) {
- return null;
- }
- result = (i == 0) ? value : result | value;
- }
-
- return result;
- }
+ @Override
+ protected long op(long result, long arg) {
+ return result | arg;
+ }
- @Override
+ @Override
protected String getExpressionOperator(int index) {
return "|";
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseRightShift.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseRightShift.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseRightShift.java
index 8e09f26..b34d3e1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseRightShift.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseRightShift.java
@@ -18,18 +18,18 @@
****************************************************************/
package org.apache.cayenne.exp.parser;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
* Bitwise right shift '>>' operation.
*
* @since 4.0
*/
-public class ASTBitwiseRightShift extends SimpleNode {
+public class ASTBitwiseRightShift extends EvaluatedBitwiseNode {
private static final long serialVersionUID = 1L;
ASTBitwiseRightShift(int id) {
@@ -41,13 +41,7 @@ public class ASTBitwiseRightShift extends SimpleNode {
}
public ASTBitwiseRightShift(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTBITWISERIGHTSHIFT);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTBitwiseRightShift(Collection<Object> nodes) {
@@ -57,28 +51,12 @@ public class ASTBitwiseRightShift extends SimpleNode {
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
+ connectChildren();
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- Long result = null;
- for (int i = 0; i < len; i++) {
- Long value = ConversionUtil.toLong(evaluateChild(i, o),
- Long.MIN_VALUE);
-
- if (value == Long.MIN_VALUE) {
- return null;
- }
-
- result = (i == 0) ? value : result >> value;
- }
-
- return result;
+ protected long op(long result, long arg) {
+ return result >> arg;
}
@Override
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java
index dfbd38b..4585d65 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTBitwiseXor.java
@@ -18,18 +18,18 @@
****************************************************************/
package org.apache.cayenne.exp.parser;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
* Bitwise exclusive disjunction (XOR or '^') operation.
*
* @since 3.1
*/
-public class ASTBitwiseXor extends SimpleNode {
+public class ASTBitwiseXor extends EvaluatedBitwiseNode {
private static final long serialVersionUID = 1L;
ASTBitwiseXor(int id) {
@@ -41,13 +41,7 @@ public class ASTBitwiseXor extends SimpleNode {
}
public ASTBitwiseXor(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTBITWISEXOR);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTBitwiseXor(Collection<Object> nodes) {
@@ -57,28 +51,13 @@ public class ASTBitwiseXor extends SimpleNode {
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
+ connectChildren();
}
-
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
- Long result = null;
- for (int i = 0; i < len; i++) {
- Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
-
- if (value == Long.MIN_VALUE) {
- return null;
- }
-
- result = (i == 0) ? value : result ^ value;
- }
-
- return result;
- }
+ @Override
+ protected long op(long result, long arg) {
+ return result ^ arg;
+ }
@Override
protected String getExpressionOperator(int index) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTConcat.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTConcat.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTConcat.java
index 1bfb336..9d4d954 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTConcat.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTConcat.java
@@ -36,10 +36,16 @@ public class ASTConcat extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
StringBuilder sb = new StringBuilder();
- for(int i=0; i<getOperandCount(); i++) {
- sb.append(ConversionUtil.toString(evaluateChild(i, o)));
+ sb.append(ConversionUtil.toString(o));
+ for(int i=1; i<evaluatedChildren.length; i++) {
+ sb.append(ConversionUtil.toString(evaluatedChildren[i]));
}
return sb.toString();
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentDate.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentDate.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentDate.java
index 035fd44..e2b3df2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentDate.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentDate.java
@@ -42,7 +42,12 @@ public class ASTCurrentDate extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
+ protected int getRequiredChildrenCount() {
+ return 0;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
return new Date();
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTime.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTime.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTime.java
index 1ef54bf..292a264 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTime.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTime.java
@@ -42,7 +42,12 @@ public class ASTCurrentTime extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
+ protected int getRequiredChildrenCount() {
+ return 0;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
return new Date();
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTimestamp.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTimestamp.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTimestamp.java
index e1d56c0..e14dd58 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTimestamp.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTimestamp.java
@@ -42,7 +42,12 @@ public class ASTCurrentTimestamp extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
+ protected int getRequiredChildrenCount() {
+ return 0;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
return new Date();
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
index 7e48b8c..b9759e1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
@@ -20,18 +20,18 @@
package org.apache.cayenne.exp.parser;
import java.math.BigDecimal;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
* "Divide" expression.
*
* @since 1.1
*/
-public class ASTDivide extends SimpleNode {
+public class ASTDivide extends EvaluatedMathNode {
private static final long serialVersionUID = -5086569683844539310L;
@@ -44,13 +44,7 @@ public class ASTDivide extends SimpleNode {
}
public ASTDivide(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTDIVIDE);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTDivide(Collection<?> nodes) {
@@ -65,24 +59,8 @@ public class ASTDivide extends SimpleNode {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- BigDecimal result = null;
- for (int i = 0; i < len; i++) {
- BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
-
- if (value == null) {
- return null;
- }
-
- result = (i == 0) ? value : result.divide(value, BigDecimal.ROUND_HALF_EVEN);
- }
-
- return result;
+ protected BigDecimal op(BigDecimal result, BigDecimal arg) {
+ return result.divide(arg, BigDecimal.ROUND_HALF_EVEN);
}
/**
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFunctionCall.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFunctionCall.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFunctionCall.java
index c8d7f06..2902db3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFunctionCall.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFunctionCall.java
@@ -27,7 +27,7 @@ import org.apache.cayenne.exp.Expression;
/**
* @since 4.0
*/
-public abstract class ASTFunctionCall extends SimpleNode {
+public abstract class ASTFunctionCall extends EvaluatedNode {
private String functionName;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLength.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLength.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLength.java
index e12512e..91247db 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLength.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLength.java
@@ -36,8 +36,8 @@ public class ASTLength extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- String s1 = ConversionUtil.toString(evaluateChild(0, o));
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ String s1 = ConversionUtil.toString(o);
if (s1 == null) {
return null;
}
@@ -45,6 +45,11 @@ public class ASTLength extends ASTFunctionCall {
}
@Override
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
public Expression shallowCopy() {
return new ASTLength(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLocate.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLocate.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLocate.java
index d26dbb5..addf4f6 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLocate.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLocate.java
@@ -40,24 +40,23 @@ public class ASTLocate extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len < 2) {
- return 0L;
- }
-
- String substr = ConversionUtil.toString(evaluateChild(0, o));
- String str = ConversionUtil.toString(evaluateChild(1, o));
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ String substr = ConversionUtil.toString(o);
+ String str = ConversionUtil.toString(evaluatedChildren[1]);
int offset = 0;
- if(len > 2) {
- offset = ConversionUtil.toInt(evaluateChild(2, o), 0);
+ if(evaluatedChildren.length > 2) {
+ offset = ConversionUtil.toInt(evaluatedChildren[2], 0);
}
-
// +1 to comply with SQL
return str.indexOf(substr, offset) + 1;
}
@Override
+ protected int getRequiredChildrenCount() {
+ return 2;
+ }
+
+ @Override
public Expression shallowCopy() {
return new ASTLocate(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLower.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLower.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLower.java
index 78b6f80..2a29a11 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLower.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLower.java
@@ -37,8 +37,13 @@ public class ASTLower extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- String s1 = ConversionUtil.toString(evaluateChild(0, o));
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ String s1 = ConversionUtil.toString(o);
if (s1 == null) {
return null;
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMod.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMod.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMod.java
index c4f79a7..268fa9c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMod.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMod.java
@@ -46,6 +46,16 @@ public class ASTMod extends ASTFunctionCall {
}
@Override
+ protected int getRequiredChildrenCount() {
+ return 0;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ return null;
+ }
+
+ @Override
public Expression shallowCopy() {
return new ASTMod(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMultiply.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMultiply.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMultiply.java
index 4b7ee0e..edc9c70 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMultiply.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTMultiply.java
@@ -20,6 +20,7 @@
package org.apache.cayenne.exp.parser;
import java.math.BigDecimal;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
@@ -31,7 +32,7 @@ import org.apache.cayenne.util.ConversionUtil;
*
* @since 1.1
*/
-public class ASTMultiply extends SimpleNode {
+public class ASTMultiply extends EvaluatedMathNode {
private static final long serialVersionUID = -8146316633842448974L;
@@ -44,13 +45,7 @@ public class ASTMultiply extends SimpleNode {
}
public ASTMultiply(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTMULTIPLY);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
-
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTMultiply(Collection<?> nodes) {
@@ -60,27 +55,12 @@ public class ASTMultiply extends SimpleNode {
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
+ connectChildren();
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- BigDecimal result = null;
- for (int i = 0; i < len; i++) {
- BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
-
- if (value == null) {
- return null;
- }
-
- result = (i == 0) ? value : result.multiply(value);
- }
-
- return result;
+ protected BigDecimal op(BigDecimal result, BigDecimal arg) {
+ return result.multiply(arg);
}
/**
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSqrt.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSqrt.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSqrt.java
index 71e8e32..41a7a4a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSqrt.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSqrt.java
@@ -36,8 +36,13 @@ public class ASTSqrt extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- double n = ConversionUtil.toDouble(evaluateChild(0, o), 0.0);
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ double n = ConversionUtil.toDouble(o, 0.0);
return Math.sqrt(n);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubstring.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubstring.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubstring.java
index 33ac4e0..de3d4af 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubstring.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubstring.java
@@ -27,7 +27,6 @@ import org.apache.cayenne.util.ConversionUtil;
*/
public class ASTSubstring extends ASTFunctionCall {
-
ASTSubstring(int id) {
super(id, "SUBSTRING");
}
@@ -37,27 +36,28 @@ public class ASTSubstring extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len != 3) {
- return null;
- }
-
- String s1 = ConversionUtil.toString(evaluateChild(0, o));
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ String s1 = ConversionUtil.toString(o);
if (s1 == null) {
return null;
}
- int offset = ConversionUtil.toInt(evaluateChild(1, o), 0);
- int length = ConversionUtil.toInt(evaluateChild(2, o), 0);
+ int offset = ConversionUtil.toInt(evaluatedChildren[1], 0);
+ int length = ConversionUtil.toInt(evaluatedChildren[2], 0);
if(length == 0) {
return null;
}
- return s1.substring(offset, offset + length);
+ return s1.substring(offset - 1, offset - 1 + length); // - 1 to comply with SQL
}
@Override
+ protected int getRequiredChildrenCount() {
+ return 3;
+ }
+
+
+ @Override
public Expression shallowCopy() {
return new ASTSubstring(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubtract.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubtract.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubtract.java
index 732b050..ce68e40 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubtract.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTSubtract.java
@@ -21,18 +21,18 @@
package org.apache.cayenne.exp.parser;
import java.math.BigDecimal;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.ConversionUtil;
/**
* "Subtract" expression.
*
* @since 1.1
*/
-public class ASTSubtract extends SimpleNode {
+public class ASTSubtract extends EvaluatedMathNode {
ASTSubtract(int id) {
super(id);
}
@@ -42,12 +42,7 @@ public class ASTSubtract extends SimpleNode {
}
public ASTSubtract(Object[] nodes) {
- super(ExpressionParserTreeConstants.JJTSUBTRACT);
- int len = nodes.length;
- for (int i = 0; i < len; i++) {
- jjtAddChild(wrapChild(nodes[i]), i);
- }
- connectChildren();
+ this(Arrays.asList(nodes));
}
public ASTSubtract(Collection<?> nodes) {
@@ -61,24 +56,8 @@ public class ASTSubtract extends SimpleNode {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len == 0) {
- return null;
- }
-
- BigDecimal result = null;
- for (int i = 0; i < len; i++) {
- BigDecimal value = ConversionUtil.toBigDecimal(evaluateChild(i, o));
-
- if (value == null) {
- return null;
- }
-
- result = (i == 0) ? value : result.subtract(value);
- }
-
- return result;
+ protected BigDecimal op(BigDecimal result, BigDecimal arg) {
+ return result.subtract(arg);
}
/**
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTTrim.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTTrim.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTTrim.java
index f037dd0..5c4af1a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTTrim.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTTrim.java
@@ -41,12 +41,16 @@ public class ASTTrim extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- String s1 = ConversionUtil.toString(evaluateChild(0, o));
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ String s1 = ConversionUtil.toString(o);
if (s1 == null) {
return null;
}
-
return s1.trim();
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTUpper.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTUpper.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTUpper.java
index 60716fc..602edd3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTUpper.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTUpper.java
@@ -36,8 +36,13 @@ public class ASTUpper extends ASTFunctionCall {
}
@Override
- protected Object evaluateNode(Object o) throws Exception {
- String s1 = ConversionUtil.toString(evaluateChild(0, o));
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ String s1 = ConversionUtil.toString(o);
if (s1 == null) {
return null;
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedBitwiseNode.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedBitwiseNode.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedBitwiseNode.java
new file mode 100644
index 0000000..c19deee
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedBitwiseNode.java
@@ -0,0 +1,57 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.exp.parser;
+
+import org.apache.cayenne.util.ConversionUtil;
+
+/**
+ * @since 4.0
+ */
+public abstract class EvaluatedBitwiseNode extends EvaluatedNode {
+
+ protected EvaluatedBitwiseNode(int i) {
+ super(i);
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ Long result = ConversionUtil.toLong(o, Long.MIN_VALUE);
+ if(result == Long.MIN_VALUE) {
+ return null;
+ }
+ for (int i = 1; i < evaluatedChildren.length; i++) {
+ Long value = ConversionUtil.toLong(evaluateChild(i, o), Long.MIN_VALUE);
+ if (value == Long.MIN_VALUE) {
+ return null;
+ }
+
+ result = op(result, value);
+ }
+
+ return result;
+ }
+
+ @Override
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ protected abstract long op(long result, long arg);
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedMathNode.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedMathNode.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedMathNode.java
new file mode 100644
index 0000000..d0177c2
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedMathNode.java
@@ -0,0 +1,58 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.exp.parser;
+
+import java.math.BigDecimal;
+
+import org.apache.cayenne.util.ConversionUtil;
+
+/**
+ * @since 4.0
+ */
+public abstract class EvaluatedMathNode extends EvaluatedNode {
+ protected EvaluatedMathNode(int i) {
+ super(i);
+ }
+
+ @Override
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ BigDecimal result = ConversionUtil.toBigDecimal(o);
+ if(result == null) {
+ return null;
+ }
+ for (int i = 1; i < evaluatedChildren.length; i++) {
+ BigDecimal value = ConversionUtil.toBigDecimal(evaluatedChildren[i]);
+ if (value == null) {
+ return null;
+ }
+ result = op(result, value);
+ }
+
+ return result;
+ }
+
+ abstract protected BigDecimal op(BigDecimal result, BigDecimal arg);
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedNode.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedNode.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedNode.java
new file mode 100644
index 0000000..96d962b
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/EvaluatedNode.java
@@ -0,0 +1,85 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.exp.parser;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @since 4.0
+ */
+public abstract class EvaluatedNode extends SimpleNode {
+
+ protected EvaluatedNode(int i) {
+ super(i);
+ }
+
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ int len = jjtGetNumChildren();
+ int requiredLen = getRequiredChildrenCount();
+ if (len < requiredLen) {
+ return null;
+ }
+
+ if(requiredLen == 0) {
+ return evaluateSubNode(null, null);
+ }
+
+ final Object[] evaluatedChildren = new Object[len];
+ for(int i=0; i<len; i++) {
+ evaluatedChildren[i] = evaluateChild(i, o);
+ }
+
+ Object firstChild = evaluatedChildren[0];
+
+ // convert Map, keep Map keys
+ if(firstChild instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map<Object, Object> child = (Map<Object, Object>) firstChild;
+ Map<Object, Object> result = new HashMap<>(child.size());
+ for(Map.Entry<Object, Object> entry : child.entrySet()) {
+ result.put(entry.getKey(), evaluateSubNode(entry.getValue(), evaluatedChildren));
+ }
+ return result;
+ }
+
+ // convert collection
+ if (firstChild instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ Collection<Object> child = (Collection<Object>) firstChild;
+ Collection<Object> result = new ArrayList<>(child.size());
+ for(Object c : child) {
+ result.add(evaluateSubNode(c, evaluatedChildren));
+ }
+ return result;
+ }
+
+ // convert scalar
+ return evaluateSubNode(firstChild, evaluatedChildren);
+ }
+
+ abstract protected int getRequiredChildrenCount();
+
+ abstract protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception;
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallStringIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallStringIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallStringIT.java
index 58a69dd..47d6373 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallStringIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallStringIT.java
@@ -163,7 +163,7 @@ public class ASTFunctionCallStringIT extends ServerCase {
@Test
public void testASTSubstringParse() {
Expression exp = ExpressionFactory.exp("SUBSTRING('123456789', 3, 2)");
- assertEquals("45", exp.evaluate(new Object()));
+ assertEquals("34", exp.evaluate(new Object()));
}
@Test
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTSubstringTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTSubstringTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTSubstringTest.java
index ee6a74a..2b35ab0 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTSubstringTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTSubstringTest.java
@@ -44,7 +44,7 @@ public class ASTSubstringTest {
Object res = exp.evaluateNode(a);
assertTrue(res instanceof String);
- assertEquals("34567890", res);
+ assertEquals("23456789", res);
}
@Test
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionCollectionEvaluationIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionCollectionEvaluationIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionCollectionEvaluationIT.java
new file mode 100644
index 0000000..685a7d4
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionCollectionEvaluationIT.java
@@ -0,0 +1,122 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.exp.parser;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.unit.di.server.CayenneProjects;
+import org.apache.cayenne.unit.di.server.ServerCase;
+import org.apache.cayenne.unit.di.server.UseServerRuntime;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @since 4.0
+ */
+@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
+public class ExpressionCollectionEvaluationIT extends ServerCase {
+
+ @Inject
+ private DataContext context;
+
+ @Inject
+ private DBHelper dbHelper;
+
+ @Before
+ public void createArtistsDataSet() throws Exception {
+ TableHelper tArtist = new TableHelper(dbHelper, "ARTIST");
+ tArtist.setColumns("ARTIST_ID", "ARTIST_NAME", "DATE_OF_BIRTH");
+ tArtist.insert(1, "artist1", new java.sql.Date(System.currentTimeMillis()));
+
+ TableHelper tGallery = new TableHelper(dbHelper, "GALLERY");
+ tGallery.setColumns("GALLERY_ID", "GALLERY_NAME");
+ tGallery.insert(1, "tate modern");
+
+ TableHelper tPaintings = new TableHelper(dbHelper, "PAINTING");
+ tPaintings.setColumns("PAINTING_ID", "PAINTING_TITLE", "ARTIST_ID", "GALLERY_ID", "ESTIMATED_PRICE");
+ for (int i = 1; i <= 3; i++) {
+ tPaintings.insert(i, i + "painting" + (Math.pow(10, i)), 1, 1, i * 100);
+ }
+
+ tPaintings.insert(4, "4painting", null, 1, 10000);
+// tPaintings.insert(5, "5painting", 1, 1, null);
+ }
+
+ @Test
+ public void testSubstringWithCollection() {
+ testExpression("SUBSTRING(paintingArray.paintingTitle, 1, 1)", String.class);
+ }
+
+ @Test
+ public void testTrimWithCollection() {
+ testExpression("TRIM(paintingArray.paintingTitle)", String.class);
+ }
+
+ @Test
+ public void testUpperWithCollection() {
+ testExpression("UPPER(paintingArray.paintingTitle)", String.class);
+ }
+
+ @Test
+ public void testLowerWithCollection() {
+ testExpression("LOWER(paintingArray.paintingTitle)", String.class);
+ }
+
+ @Test
+ public void testLengthWithCollection() {
+ testExpression("LENGTH(paintingArray.paintingTitle)", Integer.class);
+ }
+
+ @Test
+ public void testConcatWithCollection() {
+ testExpression("CONCAT(paintingArray.paintingTitle, ' ', 'xyz')", String.class);
+ }
+
+ @Test
+ public void testMathWithCollection() {
+ testExpression("paintingArray.estimatedPrice + 2", BigDecimal.class);
+ }
+
+ private <T extends Comparable<T>> void testExpression(String expStr, Class<T> tClass) {
+ Expression exp = ExpressionFactory.exp(expStr);
+ Object res = exp.evaluate(ObjectSelect.query(Artist.class).prefetch(Artist.PAINTING_ARRAY.disjoint()).selectOne(context));
+ List<T> sqlResult = ObjectSelect.query(Artist.class).column(Property.create(exp, tClass)).orderBy("db:paintingArray.PAINTING_ID").select(context);
+
+ Collections.sort((List)res);
+ Collections.sort(sqlResult);
+
+ assertEquals(3, sqlResult.size());
+ assertEquals(res, sqlResult);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/2667f012/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index 94d9729..7a1cdf7 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -31,6 +31,7 @@ CAY-2212 cdbimport cleanup and configuration schema refactoring
CAY-2223 JCacheQueryCache - a query cache provider to plug in JCache implementers
CAY-2225 Extensible CacheInvalidationFilter logic
CAY-2228 Deprecate multiple cache groups in caching and query API
+CAY-2231 Support for collections in new functional expressions and old math expressions
CAY-2232 Proper conversion to String for new functional expressions
CAY-2235 Deprecate Query.getDataMap() method