Repository: cayenne
Updated Branches:
  refs/heads/master c44ccfde3 -> 0a9430f34


CAY-2189 Date/Time functions support


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/0a9430f3
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/0a9430f3
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/0a9430f3

Branch: refs/heads/master
Commit: 0a9430f34660c13631251ecc8a57af5f439f31aa
Parents: c44ccfd
Author: Nikita Timofeev <[email protected]>
Authored: Fri Jan 20 12:40:59 2017 +0300
Committer: Nikita Timofeev <[email protected]>
Committed: Fri Jan 20 12:40:59 2017 +0300

----------------------------------------------------------------------
 .../translator/select/QualifierTranslator.java  |   6 +-
 .../dba/oracle/OracleQualifierTranslator.java   |   2 +
 .../SQLServerTrimmingQualifierTranslator.java   |   6 +
 .../cayenne/exp/FunctionExpressionFactory.java  |  24 ++++
 .../cayenne/exp/parser/ASTCurrentDate.java      |  53 +++++++++
 .../cayenne/exp/parser/ASTCurrentTime.java      |  53 +++++++++
 .../cayenne/exp/parser/ASTCurrentTimestamp.java |  53 +++++++++
 .../cayenne/exp/parser/ASTFunctionCall.java     |   4 +
 .../org/apache/cayenne/dba/ingres/types.xml     |   2 +-
 .../org/apache/cayenne/dba/sqlserver/types.xml  |   4 +-
 ...extEJBQLDateTimeFunctionalExpressionsIT.java |   6 +-
 .../apache/cayenne/exp/ExpressionFactoryIT.java |  37 ++++++
 .../exp/FunctionExpressionFactoryTest.java      |  21 ++++
 .../exp/parser/ASTFunctionCallDateIT.java       | 117 +++++++++++++++++++
 .../apache/cayenne/query/ColumnSelectIT.java    |  24 ++--
 15 files changed, 394 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
index b758b23..aad7eca 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java
@@ -538,7 +538,7 @@ public class QualifierTranslator extends 
QueryAssemblerHelper implements Travers
 
        protected boolean parenthesisNeeded(Expression node, Expression 
parentNode) {
                if (node.getType() == Expression.FUNCTION_CALL) {
-                       return true;
+                       return ((ASTFunctionCall)node).needParenthesis();
                }
 
                if (parentNode == null) {
@@ -651,7 +651,9 @@ public class QualifierTranslator extends 
QueryAssemblerHelper implements Travers
         * @since 4.0
         */
        protected void clearLastFunctionArgDivider(ASTFunctionCall 
functionExpression) {
-               out.delete(out.length() - 2, out.length());
+               if(functionExpression.getOperandCount() > 0) {
+                       out.delete(out.length() - 2, out.length());
+               }
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
index 28b9f74..011a33b 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleQualifierTranslator.java
@@ -123,6 +123,8 @@ public class OracleQualifierTranslator extends 
TrimmingQualifierTranslator {
                        // LOCATE(substr, str) -> INSTR(str, substr)
                        out.append("INSTR");
                        swapNodeChildren(functionExpression, 0, 1);
+               } else 
if("CURRENT_TIME".equals(functionExpression.getFunctionName())) {
+                       out.append("{fn CURTIME()}");
                } else {
                        super.appendFunction(functionExpression);
                }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTrimmingQualifierTranslator.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTrimmingQualifierTranslator.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTrimmingQualifierTranslator.java
index 2f03bd7..9def833 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTrimmingQualifierTranslator.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerTrimmingQualifierTranslator.java
@@ -132,6 +132,12 @@ class SQLServerTrimmingQualifierTranslator extends 
TrimmingQualifierTranslator {
                        case "TRIM":
                                out.append("LTRIM(RTRIM");
                                break;
+                       case "CURRENT_DATE":
+                               out.append("{fn CURDATE()}");
+                               break;
+                       case "CURRENT_TIME":
+                               out.append("{fn CURTIME()}");
+                               break;
                        default:
                                super.appendFunction(functionExpression);
                }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
index 0d17829..bf3dc9b 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/FunctionExpressionFactory.java
@@ -23,6 +23,9 @@ import org.apache.cayenne.exp.parser.ASTAbs;
 import org.apache.cayenne.exp.parser.ASTAvg;
 import org.apache.cayenne.exp.parser.ASTConcat;
 import org.apache.cayenne.exp.parser.ASTCount;
+import org.apache.cayenne.exp.parser.ASTCurrentDate;
+import org.apache.cayenne.exp.parser.ASTCurrentTime;
+import org.apache.cayenne.exp.parser.ASTCurrentTimestamp;
 import org.apache.cayenne.exp.parser.ASTLength;
 import org.apache.cayenne.exp.parser.ASTLocate;
 import org.apache.cayenne.exp.parser.ASTLower;
@@ -332,4 +335,25 @@ public class FunctionExpressionFactory {
     public static Expression sumExp(Expression exp) {
         return new ASTSum(exp);
     }
+
+    /**
+     * @return CURRENT_DATE expression
+     */
+    public static Expression currentDate() {
+        return new ASTCurrentDate();
+    }
+
+    /**
+     * @return CURRENT_TIME expression
+     */
+    public static Expression currentTime() {
+        return new ASTCurrentTime();
+    }
+
+    /**
+     * @return CURRENT_TIMESTAMP expression
+     */
+    public static Expression currentTimestamp() {
+        return new ASTCurrentTimestamp();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/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
new file mode 100644
index 0000000..035fd44
--- /dev/null
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentDate.java
@@ -0,0 +1,53 @@
+/*****************************************************************
+ *   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.Date;
+
+import org.apache.cayenne.exp.Expression;
+
+/**
+ * @since 4.0
+ */
+public class ASTCurrentDate extends ASTFunctionCall {
+
+    public ASTCurrentDate() {
+        this(0);
+    }
+
+    ASTCurrentDate(int id) {
+        super(id, "CURRENT_DATE");
+    }
+
+    @Override
+    public boolean needParenthesis() {
+        return false;
+    }
+
+    @Override
+    protected Object evaluateNode(Object o) throws Exception {
+        return new Date();
+    }
+
+    @Override
+    public Expression shallowCopy() {
+        return new ASTCurrentDate(id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/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
new file mode 100644
index 0000000..1ef54bf
--- /dev/null
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTime.java
@@ -0,0 +1,53 @@
+/*****************************************************************
+ *   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.Date;
+
+import org.apache.cayenne.exp.Expression;
+
+/**
+ * @since 4.0
+ */
+public class ASTCurrentTime extends ASTFunctionCall {
+
+    public ASTCurrentTime() {
+        this(0);
+    }
+
+    ASTCurrentTime(int id) {
+        super(id, "CURRENT_TIME");
+    }
+
+    @Override
+    public boolean needParenthesis() {
+        return false;
+    }
+
+    @Override
+    protected Object evaluateNode(Object o) throws Exception {
+        return new Date();
+    }
+
+    @Override
+    public Expression shallowCopy() {
+        return new ASTCurrentTime(id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/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
new file mode 100644
index 0000000..e1d56c0
--- /dev/null
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTCurrentTimestamp.java
@@ -0,0 +1,53 @@
+/*****************************************************************
+ *   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.Date;
+
+import org.apache.cayenne.exp.Expression;
+
+/**
+ * @since 4.0
+ */
+public class ASTCurrentTimestamp extends ASTFunctionCall {
+
+    public ASTCurrentTimestamp() {
+        this(0);
+    }
+
+    ASTCurrentTimestamp(int id) {
+        super(id, "CURRENT_TIMESTAMP");
+    }
+
+    @Override
+    public boolean needParenthesis() {
+        return false;
+    }
+
+    @Override
+    protected Object evaluateNode(Object o) throws Exception {
+        return new Date();
+    }
+
+    @Override
+    public Expression shallowCopy() {
+        return new ASTCurrentTimestamp(id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/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 8080a52..7ce114d 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
@@ -49,6 +49,10 @@ public abstract class ASTFunctionCall extends SimpleNode {
         return Expression.FUNCTION_CALL;
     }
 
+    public boolean needParenthesis() {
+        return true;
+    }
+
     public String getFunctionName() {
         return functionName;
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/main/resources/org/apache/cayenne/dba/ingres/types.xml
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/resources/org/apache/cayenne/dba/ingres/types.xml 
b/cayenne-server/src/main/resources/org/apache/cayenne/dba/ingres/types.xml
index 9cb4a25..1799b77 100644
--- a/cayenne-server/src/main/resources/org/apache/cayenne/dba/ingres/types.xml
+++ b/cayenne-server/src/main/resources/org/apache/cayenne/dba/ingres/types.xml
@@ -97,7 +97,7 @@
    </jdbc-type>
    <jdbc-type name="STRUCT"/>
    <jdbc-type name="TIME">
-       <db-type name="TIMESTAMP"/>
+       <db-type name="TIME"/>
    </jdbc-type>
    <jdbc-type name="TIMESTAMP">
        <db-type name="TIMESTAMP"/>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/main/resources/org/apache/cayenne/dba/sqlserver/types.xml
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/resources/org/apache/cayenne/dba/sqlserver/types.xml 
b/cayenne-server/src/main/resources/org/apache/cayenne/dba/sqlserver/types.xml
index aca1b21..63eb59e 100644
--- 
a/cayenne-server/src/main/resources/org/apache/cayenne/dba/sqlserver/types.xml
+++ 
b/cayenne-server/src/main/resources/org/apache/cayenne/dba/sqlserver/types.xml
@@ -55,7 +55,7 @@
    </jdbc-type>
    <jdbc-type name="DATALINK"/>
    <jdbc-type name="DATE">
-       <db-type name="datetime"/>
+       <db-type name="date"/>
    </jdbc-type>
    <jdbc-type name="DECIMAL">
        <db-type name="decimal"/>
@@ -92,7 +92,7 @@
    </jdbc-type>
    <jdbc-type name="STRUCT"/>
    <jdbc-type name="TIME">
-       <db-type name="datetime"/>
+       <db-type name="time"/>
    </jdbc-type>
    <jdbc-type name="TIMESTAMP">
        <db-type name="datetime"/>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDateTimeFunctionalExpressionsIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDateTimeFunctionalExpressionsIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDateTimeFunctionalExpressionsIT.java
index 8b0a25a..2f58216 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDateTimeFunctionalExpressionsIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextEJBQLDateTimeFunctionalExpressionsIT.java
@@ -68,13 +68,15 @@ public class 
DataContextEJBQLDateTimeFunctionalExpressionsIT extends ServerCase
 
         Calendar cal = Calendar.getInstance();
         int year = cal.get(Calendar.YEAR);
+        int month = cal.get(Calendar.MONTH);
+        int day = cal.get(Calendar.DAY_OF_MONTH);
 
         DateTestEntity o1 = context.newObject(DateTestEntity.class);
-        cal.set(year, 1, 1, 0, 0, 0);
+        cal.set(year, month, day, 0, 0, 0);
         o1.setTimeColumn(cal.getTime());
 
         DateTestEntity o2 = context.newObject(DateTestEntity.class);
-        cal.set(year, 1, 1, 23, 59, 59);
+        cal.set(year, month, day, 23, 59, 59);
         o2.setTimeColumn(cal.getTime());
 
         context.commitChanges();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java
index 4ab56cd..7fb78a9 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/ExpressionFactoryIT.java
@@ -19,6 +19,11 @@
 
 package org.apache.cayenne.exp;
 
+import static org.apache.cayenne.exp.ExpressionFactory.exp;
+import static org.apache.cayenne.exp.ExpressionFactory.greaterExp;
+import static org.apache.cayenne.exp.FunctionExpressionFactory.lengthExp;
+import static org.apache.cayenne.exp.FunctionExpressionFactory.substringExp;
+import static org.apache.cayenne.exp.FunctionExpressionFactory.trimExp;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -27,6 +32,7 @@ import java.util.List;
 
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.apache.cayenne.testdo.testmap.Painting;
@@ -135,4 +141,35 @@ public class ExpressionFactoryIT extends ServerCase {
                artists = context.select(q2);
                assertEquals(1, artists.size());
        }
+
+       @Test
+       public void testDifferentExpressionAPI() throws Exception {
+               List<Artist> res;
+
+               // First version via expression string
+               Expression exp1 = exp(
+                               "length(substring(artistName, 1, 3)) > 
length(trim(artistName))"
+               );
+               res = ObjectSelect.query(Artist.class, exp1).select(context);
+               assertEquals(0, res.size());
+
+               // Second version via FunctionExpressionFactory API
+               Expression exp2 = greaterExp(
+                               
lengthExp(substringExp(Artist.ARTIST_NAME.path(), 1, 3)),
+                               lengthExp(trimExp(Artist.ARTIST_NAME.path()))
+               );
+               res = ObjectSelect.query(Artist.class, exp2).select(context);
+               assertEquals(0, res.size());
+
+               // Third version via Property API
+               Property<Integer> lengthSub = 
Property.create(lengthExp(substringExp(Artist.ARTIST_NAME.path(), 1, 3)), 
Integer.class);
+               Property<Integer> length = 
Property.create(lengthExp(trimExp(Artist.ARTIST_NAME.path())), Integer.class);
+               Expression exp3 = lengthSub.gt(length);
+               res = ObjectSelect.query(Artist.class, exp3).select(context);
+               assertEquals(0, res.size());
+
+               // Check that all expressions are equal
+               assertEquals(exp1, exp2);
+               assertEquals(exp3, exp3);
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/test/java/org/apache/cayenne/exp/FunctionExpressionFactoryTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/exp/FunctionExpressionFactoryTest.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/FunctionExpressionFactoryTest.java
index fd24836..7a9859c 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/exp/FunctionExpressionFactoryTest.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/FunctionExpressionFactoryTest.java
@@ -24,6 +24,9 @@ import org.apache.cayenne.exp.parser.ASTAsterisk;
 import org.apache.cayenne.exp.parser.ASTAvg;
 import org.apache.cayenne.exp.parser.ASTConcat;
 import org.apache.cayenne.exp.parser.ASTCount;
+import org.apache.cayenne.exp.parser.ASTCurrentDate;
+import org.apache.cayenne.exp.parser.ASTCurrentTime;
+import org.apache.cayenne.exp.parser.ASTCurrentTimestamp;
 import org.apache.cayenne.exp.parser.ASTLength;
 import org.apache.cayenne.exp.parser.ASTLocate;
 import org.apache.cayenne.exp.parser.ASTLower;
@@ -243,4 +246,22 @@ public class FunctionExpressionFactoryTest {
         assertEquals(1, exp1.getOperandCount());
         assertEquals(Artist.ARTIST_NAME.path(), exp1.getOperand(0));
     }
+
+    @Test
+    public void currentDateTest() throws Exception {
+        Expression exp = FunctionExpressionFactory.currentDate();
+        assertTrue(exp instanceof ASTCurrentDate);
+    }
+
+    @Test
+    public void currentTimeTest() throws Exception {
+        Expression exp = FunctionExpressionFactory.currentTime();
+        assertTrue(exp instanceof ASTCurrentTime);
+    }
+
+    @Test
+    public void currentTimestampTest() throws Exception {
+        Expression exp = FunctionExpressionFactory.currentTimestamp();
+        assertTrue(exp instanceof ASTCurrentTimestamp);
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallDateIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallDateIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallDateIT.java
new file mode 100644
index 0000000..2c4a17d
--- /dev/null
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTFunctionCallDateIT.java
@@ -0,0 +1,117 @@
+/*****************************************************************
+ *   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.Calendar;
+import java.util.TimeZone;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.test.jdbc.DBHelper;
+import org.apache.cayenne.testdo.date_time.DateTestEntity;
+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.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @since 4.0
+ */
+@UseServerRuntime(CayenneProjects.DATE_TIME_PROJECT)
+public class ASTFunctionCallDateIT extends ServerCase {
+
+    @Inject
+    private ObjectContext context;
+
+    @Inject
+    private DBHelper dbHelper;
+
+    @Before
+    public void createDataSet() throws Exception {
+        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+        int year = cal.get(Calendar.YEAR);
+        int month = cal.get(Calendar.MONTH);
+        int day = cal.get(Calendar.DAY_OF_MONTH);
+
+        DateTestEntity o1 = context.newObject(DateTestEntity.class);
+        cal.set(year - 1, month, day, 0, 0, 0);
+        o1.setDateColumn(cal.getTime());
+        cal.set(year, month, day, 0, 0, 0);
+        o1.setTimeColumn(cal.getTime());
+        cal.set(Calendar.DAY_OF_MONTH, day - 1);
+        o1.setTimestampColumn(cal.getTime());
+
+        DateTestEntity o2 = context.newObject(DateTestEntity.class);
+        cal.set(year + 1, month, day, 0, 0, 0);
+        o2.setDateColumn(cal.getTime());
+        cal.set(year, month, day, 23, 59, 59);
+        o2.setTimeColumn(cal.getTime());
+        cal.set(Calendar.DAY_OF_MONTH, day + 1);
+        o2.setTimestampColumn(cal.getTime());
+
+        context.commitChanges();
+    }
+
+    @Test
+    public void testCurrentDate() throws Exception {
+        Expression exp = ExpressionFactory.greaterOrEqualExp("dateColumn", new 
ASTCurrentDate());
+        DateTestEntity res1 = ObjectSelect.query(DateTestEntity.class, 
exp).selectOne(context);
+        assertNotNull(res1);
+
+        Expression exp2 = ExpressionFactory.lessExp("dateColumn", new 
ASTCurrentDate());
+        DateTestEntity res2 = ObjectSelect.query(DateTestEntity.class, 
exp2).selectOne(context);
+        assertNotNull(res2);
+
+        assertNotEquals(res1, res2);
+    }
+
+    @Test
+    public void testCurrentTime() throws Exception {
+        Expression exp = ExpressionFactory.greaterOrEqualExp("timeColumn", new 
ASTCurrentTime());
+        DateTestEntity res1 = ObjectSelect.query(DateTestEntity.class, 
exp).selectOne(context);
+        assertNotNull(res1);
+
+        Expression exp2 = ExpressionFactory.lessExp("timeColumn", new 
ASTCurrentTime());
+        DateTestEntity res2 = ObjectSelect.query(DateTestEntity.class, 
exp2).selectOne(context);
+        assertNotNull(res2);
+
+        assertNotEquals(res1, res2);
+    }
+
+    @Test
+    public void testCurrentTimestamp() throws Exception {
+        Expression exp = 
ExpressionFactory.greaterOrEqualExp("timestampColumn", new 
ASTCurrentTimestamp());
+        DateTestEntity res1 = ObjectSelect.query(DateTestEntity.class, 
exp).selectOne(context);
+        assertNotNull(res1);
+
+        Expression exp2 = ExpressionFactory.lessExp("timestampColumn", new 
ASTCurrentTimestamp());
+        DateTestEntity res2 = ObjectSelect.query(DateTestEntity.class, 
exp2).selectOne(context);
+        assertNotNull(res2);
+
+        assertNotEquals(res1, res2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0a9430f3/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java 
b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
index 0874763..0e2f404 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ColumnSelectIT.java
@@ -251,11 +251,11 @@ public class ColumnSelectIT extends ServerCase {
             } else {
                 return;
             }
+        } finally {
+            
context.getEntityResolver().getDataMap("testmap").setQuotingSQLIdentifiers(false);
         }
         assertEquals("artist2", result[0]);
         assertEquals(5L, result[2]);
-
-        
context.getEntityResolver().getDataMap("testmap").setQuotingSQLIdentifiers(false);
     }
 
     @Test
@@ -268,14 +268,16 @@ public class ColumnSelectIT extends ServerCase {
         Property<Long> count = Property.create(countExp(), Long.class);
         
context.getEntityResolver().getDataMap("testmap").setQuotingSQLIdentifiers(true);
 
-        Object[] result = ColumnSelect.query(Artist.class)
-                .columns(Artist.DATE_OF_BIRTH, count)
-                .orderBy(Artist.DATE_OF_BIRTH.asc())
-                .selectFirst(context);
-
-        assertEquals(dateFormat.parse("1/1/17"), result[0]);
-        assertEquals(4L, result[1]);
-
-        
context.getEntityResolver().getDataMap("testmap").setQuotingSQLIdentifiers(false);
+        try {
+            Object[] result = ColumnSelect.query(Artist.class)
+                    .columns(Artist.DATE_OF_BIRTH, count)
+                    .orderBy(Artist.DATE_OF_BIRTH.asc())
+                    .selectFirst(context);
+
+            assertEquals(dateFormat.parse("1/1/17"), result[0]);
+            assertEquals(4L, result[1]);
+        } finally {
+            
context.getEntityResolver().getDataMap("testmap").setQuotingSQLIdentifiers(false);
+        }
     }
 }

Reply via email to