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/03/20 10:18:28 UTC
[3/3] cayenne git commit: CAY-2269 Add support for date/time
components extraction in expression functions
CAY-2269 Add support for date/time components extraction in expression functions
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/05a77250
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/05a77250
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/05a77250
Branch: refs/heads/master
Commit: 05a77250221c23aede7267835fb55d997560c5b0
Parents: e56a93f
Author: Nikita Timofeev <st...@gmail.com>
Authored: Mon Mar 20 13:00:23 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Mon Mar 20 13:00:23 2017 +0300
----------------------------------------------------------------------
.../translator/select/QualifierTranslator.java | 15 +-
.../cayenne/dba/db2/DB2QualifierTranslator.java | 20 +
.../dba/derby/DerbyQualifierTranslator.java | 17 +
.../firebird/FirebirdQualifierTranslator.java | 36 +
.../frontbase/FrontBaseQualifierTranslator.java | 34 +
.../dba/hsqldb/HSQLQualifierTranslator.java | 15 +
.../dba/ingres/IngresQualifierTranslator.java | 15 +
.../dba/mysql/MySQLQualifierTranslator.java | 15 +
.../openbase/OpenBaseQualifierTranslator.java | 15 +
.../dba/oracle/OracleQualifierTranslator.java | 47 +
.../postgres/PostgresQualifierTranslator.java | 37 +
.../cayenne/dba/sqlite/SQLiteAdapter.java | 4 +-
.../cayenne/dba/sqlite/SQLiteDateType.java | 70 +-
.../dba/sqlite/SQLiteQualifierTranslator.java | 60 ++
.../SQLServerTrimmingQualifierTranslator.java | 35 +
.../dba/sybase/SybaseQualifierTranslator.java | 36 +
.../cayenne/exp/FunctionExpressionFactory.java | 155 +++
.../cayenne/exp/parser/ASTCurrentDate.java | 5 -
.../cayenne/exp/parser/ASTCurrentTime.java | 5 -
.../cayenne/exp/parser/ASTCurrentTimestamp.java | 5 -
.../apache/cayenne/exp/parser/ASTExtract.java | 125 +++
.../cayenne/exp/parser/ASTFunctionCall.java | 24 +-
.../cayenne/exp/parser/ExpressionParser.java | 302 ++++--
.../exp/parser/ExpressionParserConstants.java | 64 +-
.../parser/ExpressionParserTokenManager.java | 979 ++++++++++---------
.../parser/ExpressionParserTreeConstants.java | 10 +-
.../cayenne/exp/parser/ExpressionParser.jjt | 49 +-
.../cayenne/exp/parser/ASTCurrentDateTest.java | 51 +
.../cayenne/exp/parser/ASTCurrentTimeTest.java | 50 +
.../exp/parser/ASTCurrentTimestampTest.java | 54 +
.../apache/cayenne/exp/parser/ASTExtractIT.java | 240 +++++
.../cayenne/exp/parser/ASTExtractTest.java | 162 +++
.../apache/cayenne/unit/DerbyUnitDbAdapter.java | 12 +
.../cayenne/unit/FrontBaseUnitDbAdapter.java | 11 +
.../org/apache/cayenne/unit/UnitDbAdapter.java | 5 +
.../ServerCaseDataSourceInfoProvider.java | 2 +-
docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 +
37 files changed, 2161 insertions(+), 621 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 aad7eca..deb7d52 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
@@ -30,6 +30,7 @@ import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.TraversalHandler;
import org.apache.cayenne.exp.parser.ASTDbPath;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.ASTObjPath;
import org.apache.cayenne.exp.parser.PatternMatchNode;
@@ -413,7 +414,11 @@ public class QualifierTranslator extends QueryAssemblerHelper implements Travers
boolean parenthesisNeeded = parenthesisNeeded(node, parentNode);
if(node.getType() == Expression.FUNCTION_CALL) {
- appendFunction((ASTFunctionCall)node);
+ if(node instanceof ASTExtract) {
+ appendExtractFunction((ASTExtract) node);
+ } else {
+ appendFunction((ASTFunctionCall) node);
+ }
if(parenthesisNeeded) {
out.append("(");
}
@@ -623,6 +628,14 @@ public class QualifierTranslator extends QueryAssemblerHelper implements Travers
}
/**
+ * Special case for extract date/time parts functions as they have many variants
+ * @since 4.0
+ */
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ appendFunction(functionExpression);
+ }
+
+ /**
* Append scalar argument of a function call
* Used only for values stored in ASTScalar other
* expressions appended in objectNode() method
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2QualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2QualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2QualifierTranslator.java
index 09b369a..6a60233 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2QualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2QualifierTranslator.java
@@ -28,6 +28,7 @@ import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator;
import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.parser.ASTEqual;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.ASTNotEqual;
import org.apache.cayenne.exp.parser.SimpleNode;
@@ -151,4 +152,23 @@ public class DB2QualifierTranslator extends TrimmingQualifierTranslator {
super.clearLastFunctionArgDivider(functionExpression);
}
}
+
+ /**
+ * @since 4.0
+ */
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ switch (functionExpression.getPart()) {
+ case DAY_OF_MONTH:
+ out.append("DAY");
+ break;
+ case DAY_OF_WEEK:
+ case DAY_OF_YEAR:
+ // db2 variants are without '_'
+ out.append(functionExpression.getPart().name().replace("_", ""));
+ break;
+ default:
+ appendFunction(functionExpression);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyQualifierTranslator.java
index 84c5889..2767417 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyQualifierTranslator.java
@@ -21,10 +21,12 @@ package org.apache.cayenne.dba.derby;
import java.io.IOException;
import java.sql.Types;
+import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.parser.ASTEqual;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.ASTNotEqual;
import org.apache.cayenne.exp.parser.SimpleNode;
@@ -120,4 +122,19 @@ public class DerbyQualifierTranslator extends TrimmingQualifierTranslator {
super.clearLastFunctionArgDivider(functionExpression);
}
}
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ switch (functionExpression.getPart()) {
+ case DAY_OF_MONTH:
+ out.append("DAY");
+ break;
+ case DAY_OF_WEEK:
+ case DAY_OF_YEAR:
+ case WEEK:
+ throw new CayenneRuntimeException("Function " + functionExpression.getPartCamelCaseName() + "() is unsupported in Derby.");
+ default:
+ super.appendExtractFunction(functionExpression);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdQualifierTranslator.java
index 503358f..eae42f7 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdQualifierTranslator.java
@@ -23,6 +23,7 @@ import org.apache.cayenne.access.translator.select.QualifierTranslator;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.dba.oracle.OracleQualifierTranslator;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import java.io.IOException;
@@ -141,5 +142,40 @@ public class FirebirdQualifierTranslator extends QualifierTranslator {
default:
super.clearLastFunctionArgDivider(functionExpression);
}
+ if(functionExpression instanceof ASTExtract) {
+ out.append(")");
+ }
+ }
+
+ @Override
+ protected boolean parenthesisNeeded(Expression node, Expression parentNode) {
+ if (node.getType() == Expression.FUNCTION_CALL) {
+ if (node instanceof ASTExtract) {
+ return false;
+ }
+ }
+
+ return super.parenthesisNeeded(node, parentNode);
+ }
+
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ out.append("EXTRACT(");
+ switch (functionExpression.getPart()) {
+ case DAY_OF_MONTH:
+ out.append("DAY");
+ break;
+ case DAY_OF_WEEK:
+ out.append("WEEKDAY");
+ break;
+ case DAY_OF_YEAR:
+ out.append("YEARDAY");
+ break;
+ default:
+ out.append(functionExpression.getPartCamelCaseName());
+ }
+
+ out.append(" FROM ");
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseQualifierTranslator.java
index 615bf68..8315a4c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseQualifierTranslator.java
@@ -19,8 +19,11 @@
package org.apache.cayenne.dba.frontbase;
+import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.translator.select.QualifierTranslator;
import org.apache.cayenne.access.translator.select.QueryAssembler;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
/**
@@ -96,5 +99,36 @@ public class FrontBaseQualifierTranslator extends QualifierTranslator {
default:
super.clearLastFunctionArgDivider(functionExpression);
}
+ if(functionExpression instanceof ASTExtract) {
+ out.append(")");
+ }
+ }
+
+ @Override
+ protected boolean parenthesisNeeded(Expression node, Expression parentNode) {
+ if (node.getType() == Expression.FUNCTION_CALL) {
+ if (node instanceof ASTExtract) {
+ return false;
+ }
+ }
+
+ return super.parenthesisNeeded(node, parentNode);
+ }
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ out.append("EXTRACT(");
+ switch (functionExpression.getPart()) {
+ case DAY_OF_WEEK:
+ case DAY_OF_YEAR:
+ case WEEK:
+ throw new CayenneRuntimeException("Function " + functionExpression.getPartCamelCaseName() + "() is unsupported in FrontBase.");
+ case DAY_OF_MONTH:
+ out.append("DAY");
+ break;
+ default:
+ out.append(functionExpression.getPart().name());
+ }
+ out.append(" FROM ");
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLQualifierTranslator.java
index bc3990d..513a707 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLQualifierTranslator.java
@@ -24,6 +24,7 @@ import java.io.IOException;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.PatternMatchNode;
@@ -69,4 +70,18 @@ public class HSQLQualifierTranslator extends TrimmingQualifierTranslator {
super.appendFunction(functionExpression);
}
}
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ switch (functionExpression.getPart()) {
+ case DAY_OF_WEEK:
+ case DAY_OF_MONTH:
+ case DAY_OF_YEAR:
+ // hsqldb variants are without '_'
+ out.append(functionExpression.getPart().name().replace("_", ""));
+ break;
+ default:
+ appendFunction(functionExpression);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresQualifierTranslator.java
index 222fe96..8334ff4 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresQualifierTranslator.java
@@ -24,6 +24,7 @@ import java.io.IOException;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.Node;
@@ -98,6 +99,20 @@ class IngresQualifierTranslator extends TrimmingQualifierTranslator {
}
}
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ switch (functionExpression.getPart()) {
+ case DAY_OF_WEEK:
+ case DAY_OF_MONTH:
+ case DAY_OF_YEAR:
+ // ingres variants are without '_'
+ out.append(functionExpression.getPart().name().replace("_", ""));
+ break;
+ default:
+ appendFunction(functionExpression);
+ }
+ }
+
private void swapNodeChildren(Node node, int i, int j) {
Node ni = node.jjtGetChild(i);
Node nj = node.jjtGetChild(j);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLQualifierTranslator.java
index 77f4dde..ac520e2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLQualifierTranslator.java
@@ -24,6 +24,7 @@ import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.translator.select.QualifierTranslator;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.PatternMatchNode;
class MySQLQualifierTranslator extends QualifierTranslator {
@@ -88,4 +89,18 @@ class MySQLQualifierTranslator extends QualifierTranslator {
}
}
}
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ switch (functionExpression.getPart()) {
+ case DAY_OF_WEEK:
+ case DAY_OF_MONTH:
+ case DAY_OF_YEAR:
+ // mysql variants are without '_'
+ out.append(functionExpression.getPart().name().replace("_", ""));
+ break;
+ default:
+ appendFunction(functionExpression);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseQualifierTranslator.java
index 42383b9..dbedc60 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseQualifierTranslator.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.translator.select.QualifierTranslator;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.PatternMatchNode;
import org.apache.cayenne.map.DbAttribute;
@@ -159,4 +160,18 @@ public class OpenBaseQualifierTranslator extends QualifierTranslator {
objectMatchTranslator.setExpression(node);
}
}
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ switch (functionExpression.getPart()) {
+ case DAY_OF_WEEK:
+ case DAY_OF_MONTH:
+ case DAY_OF_YEAR:
+ // openbase variants are without '_'
+ out.append(functionExpression.getPart().name().replace("_", ""));
+ break;
+ default:
+ appendFunction(functionExpression);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 011a33b..fadd468 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
@@ -21,6 +21,7 @@ package org.apache.cayenne.dba.oracle;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.ASTIn;
import org.apache.cayenne.exp.parser.ASTList;
@@ -152,6 +153,52 @@ public class OracleQualifierTranslator extends TrimmingQualifierTranslator {
} else {
super.clearLastFunctionArgDivider(functionExpression);
}
+
+ if(functionExpression instanceof ASTExtract) {
+ switch (((ASTExtract)functionExpression).getPart()) {
+ case DAY_OF_YEAR:
+ out.append(", 'DDD'");
+ break;
+ case DAY_OF_WEEK:
+ out.append(", 'D'");
+ break;
+ case WEEK:
+ out.append(", 'IW'");
+ break;
+ }
+ out.append(")");
+ }
+ }
+
+ @Override
+ protected boolean parenthesisNeeded(Expression node, Expression parentNode) {
+ if (node.getType() == Expression.FUNCTION_CALL) {
+ if (node instanceof ASTExtract) {
+ return false;
+ }
+ }
+
+ return super.parenthesisNeeded(node, parentNode);
+ }
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ switch (functionExpression.getPart()) {
+ // use TO_CHAR(date, format) function for parts that is unsupported by EXTRACT()
+ case DAY_OF_YEAR:
+ case DAY_OF_WEEK:
+ case WEEK:
+ out.append("TO_CHAR(");
+ break;
+ case DAY_OF_MONTH:
+ out.append("EXTRACT(DAY FROM ");
+ break;
+ default:
+ out.append("EXTRACT(");
+ out.append(functionExpression.getPart().name());
+ out.append(" FROM ");
+ }
+
}
/**
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresQualifierTranslator.java
index 42937bb..3fdc22c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresQualifierTranslator.java
@@ -25,6 +25,7 @@ import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.PatternMatchNode;
@@ -148,5 +149,41 @@ public class PostgresQualifierTranslator extends TrimmingQualifierTranslator {
} else {
super.clearLastFunctionArgDivider(functionExpression);
}
+
+ if(functionExpression instanceof ASTExtract) {
+ out.append(")");
+ }
+ }
+
+ @Override
+ protected boolean parenthesisNeeded(Expression node, Expression parentNode) {
+ if (node.getType() == Expression.FUNCTION_CALL) {
+ if (node instanceof ASTExtract) {
+ return false;
+ }
+ }
+
+ return super.parenthesisNeeded(node, parentNode);
+ }
+
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ out.append("EXTRACT(");
+ switch (functionExpression.getPart()) {
+ case DAY_OF_MONTH:
+ out.append("day");
+ break;
+ case DAY_OF_WEEK:
+ out.append("dow");
+ break;
+ case DAY_OF_YEAR:
+ out.append("doy");
+ break;
+ default:
+ out.append(functionExpression.getPartCamelCaseName());
+ }
+
+ out.append(" FROM ");
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java
index b390ebc..1796700 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java
@@ -79,8 +79,8 @@ public class SQLiteAdapter extends JdbcAdapter {
map.registerType(new SQLiteBigDecimalType());
map.registerType(new SQLiteFloatType());
map.registerType(new SQLiteByteArrayType());
- map.registerType(new SQLiteCalendarType(GregorianCalendar.class));
- map.registerType(new SQLiteCalendarType(Calendar.class));
+ map.registerType(new SQLiteCalendarType<>(GregorianCalendar.class));
+ map.registerType(new SQLiteCalendarType<>(Calendar.class));
}
/**
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
index 0dba203..497cc81 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
@@ -39,48 +39,27 @@ import org.apache.cayenne.access.types.UtilDateType;
// handling fun.
class SQLiteDateType extends UtilDateType {
- private DateFormat timestampFormat;
- private DateFormat dateFormat;
- private DateFormat timeFormat;
+ private final DateFormat timestampFormat;
+ private final DateFormat dateFormat;
+ private final DateFormat timeFormat;
public SQLiteDateType() {
- timestampFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
+ timestampFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS");
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
timeFormat = new SimpleDateFormat("kk:mm:ss");
}
@Override
public Date materializeObject(ResultSet rs, int index, int type) throws Exception {
-
- String string = rs.getString(index);
-
- if (string == null) {
- return null;
- }
-
- long ts = getLongTimestamp(string);
- if (ts >= 0) {
- return new Date(ts);
- }
-
- switch (type) {
- case Types.TIMESTAMP:
- return getTimestamp(string);
- case Types.DATE:
- return getDate(string);
- case Types.TIME:
- return rs.getTime(index);
- default:
- return getTimestamp(string);
- }
+ return parseDate(rs.getString(index), type);
}
@Override
- public Date materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
-
- String string = rs.getString(index);
+ public Date materializeObject(CallableStatement rs, int index, int type) throws Exception {
+ return parseDate(rs.getString(index), type);
+ }
+ protected Date parseDate(String string, int type) throws SQLException {
if (string == null) {
return null;
}
@@ -91,12 +70,10 @@ class SQLiteDateType extends UtilDateType {
}
switch (type) {
- case Types.TIMESTAMP:
- return getTimestamp(string);
- case Types.DATE:
- return getDate(string);
case Types.TIME:
return getTime(string);
+ case Types.DATE:
+ case Types.TIMESTAMP:
default:
return getTimestamp(string);
}
@@ -107,17 +84,9 @@ class SQLiteDateType extends UtilDateType {
synchronized (timestampFormat) {
return timestampFormat.parse(string);
}
- }
- catch (ParseException e) {
+ } catch (ParseException e) {
// also try date format...
- try {
- synchronized (dateFormat) {
- return dateFormat.parse(string);
- }
- }
- catch (ParseException e1) {
- throw new SQLException("Unparsable timestamp string: " + string);
- }
+ return getDate(string);
}
}
@@ -126,9 +95,8 @@ class SQLiteDateType extends UtilDateType {
synchronized (dateFormat) {
return dateFormat.parse(string);
}
- }
- catch (ParseException e) {
- throw new SQLException("Unparsable date string: " + string);
+ } catch (ParseException e) {
+ throw new SQLException("Unparsable date/time string: " + string);
}
}
@@ -137,17 +105,15 @@ class SQLiteDateType extends UtilDateType {
synchronized (timeFormat) {
return timeFormat.parse(string);
}
- }
- catch (ParseException e) {
- throw new SQLException("Unparsable time string: " + string);
+ } catch (ParseException e) {
+ return getTimestamp(string);
}
}
protected long getLongTimestamp(String string) {
try {
return Long.parseLong(string);
- }
- catch (NumberFormatException e) {
+ } catch (NumberFormatException e) {
return -1;
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteQualifierTranslator.java
index bc2bb2e..d31019b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteQualifierTranslator.java
@@ -22,6 +22,7 @@ package org.apache.cayenne.dba.sqlite;
import org.apache.cayenne.access.translator.select.QualifierTranslator;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.exp.parser.Node;
@@ -91,6 +92,65 @@ public class SQLiteQualifierTranslator extends QualifierTranslator {
default:
super.clearLastFunctionArgDivider(functionExpression);
}
+ if(functionExpression instanceof ASTExtract) {
+ out.append(") as integer)");
+ }
+ }
+
+ @Override
+ protected boolean parenthesisNeeded(Expression node, Expression parentNode) {
+ if (node.getType() == Expression.FUNCTION_CALL) {
+ if (node instanceof ASTExtract) {
+ return false;
+ }
+ }
+
+ return super.parenthesisNeeded(node, parentNode);
+ }
+
+
+ /**
+ * Translates to cast(strftime('format', column) as integer).
+ * Depends on connection property "date_class", can be set in connection URL (date_class=text).
+ *
+ * https://www.sqlite.org/lang_datefunc.html
+ */
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ out.append("cast(strftime(");
+
+ switch (functionExpression.getPart()) {
+ case YEAR:
+ out.append("'%Y'");
+ break;
+ case MONTH:
+ out.append("'%m'");
+ break;
+ case WEEK:
+ out.append("'%W'");
+ break;
+ case DAY:
+ case DAY_OF_MONTH:
+ out.append("'%d'");
+ break;
+ case DAY_OF_WEEK:
+ out.append("'%w'");
+ break;
+ case DAY_OF_YEAR:
+ out.append("'%j'");
+ break;
+ case HOUR:
+ out.append("'%H'");
+ break;
+ case MINUTE:
+ out.append("'%M'");
+ break;
+ case SECOND:
+ out.append("'%S'");
+ break;
+ }
+
+ out.append(", ");
}
private void swapNodeChildren(Node node, int i, int j) {
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 9def833..9847742 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
@@ -21,6 +21,7 @@ package org.apache.cayenne.dba.sqlserver;
import org.apache.cayenne.access.translator.select.QueryAssembler;
import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
import org.apache.cayenne.map.DbAttribute;
@@ -168,5 +169,39 @@ class SQLServerTrimmingQualifierTranslator extends TrimmingQualifierTranslator {
out.append(")");
}
}
+
+ if(functionExpression instanceof ASTExtract) {
+ out.append(")");
+ }
+ }
+
+ @Override
+ protected boolean parenthesisNeeded(Expression node, Expression parentNode) {
+ if (node.getType() == Expression.FUNCTION_CALL) {
+ if (node instanceof ASTExtract) {
+ return false;
+ }
+ }
+
+ return super.parenthesisNeeded(node, parentNode);
+ }
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ out.append("DATEPART(");
+ switch (functionExpression.getPart()) {
+ case DAY_OF_MONTH:
+ out.append("DAY");
+ break;
+ case DAY_OF_WEEK:
+ out.append("WEEKDAY");
+ break;
+ case DAY_OF_YEAR:
+ out.append("DAYOFYEAR");
+ break;
+ default:
+ out.append(functionExpression.getPart().name());
+ }
+ out.append(" , ");
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseQualifierTranslator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseQualifierTranslator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseQualifierTranslator.java
index 1ad939e..0f6e239 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseQualifierTranslator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseQualifierTranslator.java
@@ -21,6 +21,8 @@ package org.apache.cayenne.dba.sybase;
import org.apache.cayenne.access.translator.select.QualifierTranslator;
import org.apache.cayenne.access.translator.select.QueryAssembler;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.parser.ASTExtract;
import org.apache.cayenne.exp.parser.ASTFunctionCall;
/**
@@ -74,5 +76,39 @@ public class SybaseQualifierTranslator extends QualifierTranslator {
default:
super.clearLastFunctionArgDivider(functionExpression);
}
+
+ if(functionExpression instanceof ASTExtract) {
+ out.append(")");
+ }
+ }
+
+ @Override
+ protected boolean parenthesisNeeded(Expression node, Expression parentNode) {
+ if (node.getType() == Expression.FUNCTION_CALL) {
+ if (node instanceof ASTExtract) {
+ return false;
+ }
+ }
+
+ return super.parenthesisNeeded(node, parentNode);
+ }
+
+ @Override
+ protected void appendExtractFunction(ASTExtract functionExpression) {
+ out.append("datepart(");
+ switch (functionExpression.getPart()) {
+ case DAY_OF_MONTH:
+ out.append("day");
+ break;
+ case DAY_OF_WEEK:
+ out.append("weekday");
+ break;
+ case DAY_OF_YEAR:
+ out.append("dayofyear");
+ break;
+ default:
+ out.append(functionExpression.getPart().name().toLowerCase());
+ }
+ out.append(" , ");
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 e4cbf07..114fb1d 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
@@ -26,6 +26,7 @@ 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.ASTExtract;
import org.apache.cayenne.exp.parser.ASTLength;
import org.apache.cayenne.exp.parser.ASTLocate;
import org.apache.cayenne.exp.parser.ASTLower;
@@ -370,4 +371,158 @@ public class FunctionExpressionFactory {
public static Expression currentTimestamp() {
return new ASTCurrentTimestamp();
}
+
+ /**
+ * @param exp date/timestamp expression
+ * @return year(exp) function expression
+ */
+ public static Expression yearExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.YEAR);
+ }
+
+ /**
+ * @param path String path
+ * @return year(path) function expression
+ */
+ public static Expression yearExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.YEAR);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return month(exp) function expression
+ */
+ public static Expression monthExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.MONTH);
+ }
+
+ /**
+ * @param path String path
+ * @return month(path) function expression
+ */
+ public static Expression monthExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.MONTH);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return week(exp) function expression
+ */
+ public static Expression weekExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.WEEK);
+ }
+
+ /**
+ * @param path String path
+ * @return week(path) function expression
+ */
+ public static Expression weekExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.WEEK);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return dayOfYear(exp) function expression
+ */
+ public static Expression dayOfYearExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.DAY_OF_YEAR);
+ }
+
+ /**
+ * @param path String path
+ * @return dayOfYear(path) function expression
+ */
+ public static Expression dayOfYearExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.DAY_OF_YEAR);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return dayOfMonth(exp) function expression, synonym for day()
+ */
+ public static Expression dayOfMonthExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.DAY_OF_MONTH);
+ }
+
+ /**
+ * @param path String path
+ * @return dayOfMonth(path) function expression, synonym for day()
+ */
+ public static Expression dayOfMonthExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.DAY_OF_MONTH);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return dayOfWeek(exp) function expression
+ */
+ public static Expression dayOfWeekExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.DAY_OF_WEEK);
+ }
+
+ /**
+ * @param path String path
+ * @return dayOfWeek(path) function expression
+ */
+ public static Expression dayOfWeekExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.DAY_OF_WEEK);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return hour(exp) function expression
+ */
+ public static Expression hourExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.HOUR);
+ }
+
+ /**
+ * @param path String path
+ * @return hour(path) function expression
+ */
+ public static Expression hourExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.HOUR);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return minute(exp) function expression
+ */
+ public static Expression minuteExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.MINUTE);
+ }
+
+ /**
+ * @param path String path
+ * @return minute(path) function expression
+ */
+ public static Expression minuteExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.MINUTE);
+ }
+
+ /**
+ * @param exp date/timestamp expression
+ * @return second(exp) function expression
+ */
+ public static Expression secondExp(Expression exp) {
+ return extractExp(exp, ASTExtract.DateTimePart.SECOND);
+ }
+
+ /**
+ * @param path String path
+ * @return second(path) function expression
+ */
+ public static Expression secondExp(String path) {
+ return extractExp(path, ASTExtract.DateTimePart.SECOND);
+ }
+
+ static Expression extractExp(String path, ASTExtract.DateTimePart part) {
+ return extractExp(ExpressionFactory.pathExp(path), part);
+ }
+
+ static Expression extractExp(Expression exp, ASTExtract.DateTimePart part) {
+ ASTExtract extract = new ASTExtract(exp);
+ extract.setPart(part);
+ return extract;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 e453e8f..73743df 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
@@ -53,11 +53,6 @@ public class ASTCurrentDate extends ASTFunctionCall {
}
@Override
- protected void appendFunctionNameAsString(Appendable out) throws IOException {
- out.append("currentDate");
- }
-
- @Override
public Expression shallowCopy() {
return new ASTCurrentDate(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 feb9dfa..6cee32c 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
@@ -53,11 +53,6 @@ public class ASTCurrentTime extends ASTFunctionCall {
}
@Override
- protected void appendFunctionNameAsString(Appendable out) throws IOException {
- out.append("currentTime");
- }
-
- @Override
public Expression shallowCopy() {
return new ASTCurrentTime(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 df55492..9edf263 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
@@ -53,11 +53,6 @@ public class ASTCurrentTimestamp extends ASTFunctionCall {
}
@Override
- protected void appendFunctionNameAsString(Appendable out) throws IOException {
- out.append("currentTimestamp");
- }
-
- @Override
public Expression shallowCopy() {
return new ASTCurrentTimestamp(id);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTExtract.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTExtract.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTExtract.java
new file mode 100644
index 0000000..184d298
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTExtract.java
@@ -0,0 +1,125 @@
+/*****************************************************************
+ * 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.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.exp.Expression;
+
+public class ASTExtract extends ASTFunctionCall {
+
+ /**
+ * Available components of date/time.
+ * Names must be in sync with tokens used in dateTimeExtractingFunction() rule in ExpressionParser.jjt
+ */
+ public enum DateTimePart {
+ YEAR, MONTH, WEEK,
+ // day options, day is synonym for dayOfMonth
+ DAY_OF_YEAR, DAY, DAY_OF_MONTH, DAY_OF_WEEK,
+ HOUR, MINUTE, SECOND
+ }
+
+ /**
+ * Map from camelCase name to enum elements.
+ * @see ASTFunctionCall#nameToCamelCase(String)
+ */
+ private static final Map<String, DateTimePart> NAME_TO_PART = new HashMap<>();
+ static {
+ for(DateTimePart part : DateTimePart.values()) {
+ NAME_TO_PART.put(nameToCamelCase(part.name()), part);
+ }
+ }
+
+ /**
+ * camelCase name, found in ExpressionParser.jjt tokens
+ */
+ private String partName;
+
+ private DateTimePart part;
+
+ ASTExtract(int id) {
+ super(id, "EXTRACT");
+ }
+
+ public ASTExtract(Expression expression) {
+ super(ExpressionParserTreeConstants.JJTEXTRACT, "EXTRACT", expression);
+ }
+
+ @Override
+ public String getFunctionName() {
+ return part.name();
+ }
+
+ @Override
+ protected void appendFunctionNameAsString(Appendable out) throws IOException {
+ out.append(partName);
+ }
+
+ /**
+ * This method is used by {@link ExpressionParser}
+ * @param partToken {@link Token#image} from {@link ExpressionParser}
+ */
+ void setPartToken(String partToken) {
+ part = NAME_TO_PART.get(partToken);
+ if(part == null) {
+ throw new CayenneRuntimeException("Unknown timestamp part: " + partToken);
+ }
+ this.partName = partToken;
+ }
+
+ /**
+ * This method is used by FunctionExpressionFactory
+ * @param part date/time part to extract
+ */
+ public void setPart(DateTimePart part) {
+ this.part = part;
+ this.partName = nameToCamelCase(part.name());
+ }
+
+ public DateTimePart getPart() {
+ return part;
+ }
+
+ public String getPartCamelCaseName() {
+ return partName;
+ }
+
+ @Override
+ public Expression shallowCopy() {
+ ASTExtract copy = new ASTExtract(id);
+ copy.partName = partName;
+ copy.part = part;
+ return copy;
+ }
+
+ @Override
+ protected int getRequiredChildrenCount() {
+ return 1;
+ }
+
+ @Override
+ protected Object evaluateSubNode(Object o, Object[] evaluatedChildren) throws Exception {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/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 d31c148..3766793 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
@@ -80,7 +80,7 @@ public abstract class ASTFunctionCall extends EvaluatedNode {
}
protected void appendFunctionNameAsString(Appendable out) throws IOException {
- out.append(getFunctionName().toLowerCase());
+ out.append(nameToCamelCase(getFunctionName()));
}
@Override
@@ -103,4 +103,26 @@ public abstract class ASTFunctionCall extends EvaluatedNode {
super.appendChildrenAsEJBQL(parameterAccumulator, out, rootId);
out.append(")");
}
+
+ /**
+ *
+ * @param functionName in UPPER_UNDERSCORE convention
+ * @return functionName in camelCase convention
+ */
+ protected static String nameToCamelCase(String functionName) {
+ String[] parts = functionName.split("_");
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for(String part : parts) {
+ if(first) {
+ sb.append(part.toLowerCase());
+ first = false;
+ } else {
+ char[] chars = part.toLowerCase().toCharArray();
+ chars[0] = Character.toTitleCase(chars[0]);
+ sb.append(chars);
+ }
+ }
+ return sb.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
index 732110d..ff0fde8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
@@ -184,10 +184,20 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case CURRENT_DATE:
case CURRENT_TIME:
case CURRENT_TIMESTAMP:
- case 54:
- case 55:
- case 56:
- case 57:
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
case SINGLE_QUOTED_STRING:
case DOUBLE_QUOTED_STRING:
@@ -251,10 +261,20 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case CURRENT_DATE:
case CURRENT_TIME:
case CURRENT_TIMESTAMP:
- case 54:
- case 55:
- case 56:
- case 57:
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
case SINGLE_QUOTED_STRING:
case DOUBLE_QUOTED_STRING:
@@ -524,7 +544,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
jjtree.openNodeScope(jjtn011);
try {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case 54:
+ case 64:
namedParameter();
break;
case 16:
@@ -683,7 +703,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
jjtree.openNodeScope(jjtn003);
try {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case 54:
+ case 64:
namedParameter();
break;
case 16:
@@ -803,10 +823,20 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case ABS:
case SQRT:
case MOD:
- case 54:
- case 55:
- case 56:
- case 57:
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
case INT_LITERAL:
case FLOAT_LITERAL:
@@ -854,9 +884,9 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
final public void stringParameter() throws ParseException {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case 55:
- case 56:
- case 57:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
pathExpression();
break;
@@ -947,10 +977,20 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case CURRENT_DATE:
case CURRENT_TIME:
case CURRENT_TIMESTAMP:
- case 54:
- case 55:
- case 56:
- case 57:
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
case SINGLE_QUOTED_STRING:
case DOUBLE_QUOTED_STRING:
@@ -1027,22 +1067,22 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
}
break;
- case 54:
+ case 64:
namedParameter();
break;
case INT_LITERAL:
jj_consume_token(INT_LITERAL);
- ASTScalar jjtn003 = new ASTScalar(JJTSCALAR);
- boolean jjtc003 = true;
- jjtree.openNodeScope(jjtn003);
+ ASTScalar jjtn003 = new ASTScalar(JJTSCALAR);
+ boolean jjtc003 = true;
+ jjtree.openNodeScope(jjtn003);
try {
- jjtree.closeNodeScope(jjtn003, 0);
- jjtc003 = false;
- jjtn003.setValue(token_source.literalValue);
- } finally {
- if (jjtc003) {
jjtree.closeNodeScope(jjtn003, 0);
- }
+ jjtc003 = false;
+ jjtn003.setValue(token_source.literalValue);
+ } finally {
+ if (jjtc003) {
+ jjtree.closeNodeScope(jjtn003, 0);
+ }
}
break;
case FLOAT_LITERAL:
@@ -1062,17 +1102,17 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
break;
case TRUE:
jj_consume_token(TRUE);
- ASTScalar jjtn005 = new ASTScalar(JJTSCALAR);
- boolean jjtc005 = true;
- jjtree.openNodeScope(jjtn005);
+ ASTScalar jjtn005 = new ASTScalar(JJTSCALAR);
+ boolean jjtc005 = true;
+ jjtree.openNodeScope(jjtn005);
try {
- jjtree.closeNodeScope(jjtn005, 0);
- jjtc005 = false;
- jjtn005.setValue(true);
+ jjtree.closeNodeScope(jjtn005, 0);
+ jjtc005 = false;
+ jjtn005.setValue(true);
} finally {
- if (jjtc005) {
- jjtree.closeNodeScope(jjtn005, 0);
- }
+ if (jjtc005) {
+ jjtree.closeNodeScope(jjtn005, 0);
+ }
}
break;
case FALSE:
@@ -1459,10 +1499,20 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case ABS:
case SQRT:
case MOD:
- case 54:
- case 55:
- case 56:
- case 57:
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
case INT_LITERAL:
case FLOAT_LITERAL:
@@ -1511,10 +1561,20 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case ABS:
case SQRT:
case MOD:
- case 54:
- case 55:
- case 56:
- case 57:
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
case INT_LITERAL:
case FLOAT_LITERAL:
@@ -1599,7 +1659,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
}
break;
- case 54:
+ case 64:
namedParameter();
break;
case LENGTH:
@@ -1607,11 +1667,21 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case ABS:
case SQRT:
case MOD:
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
functionsReturningNumerics();
break;
- case 55:
- case 56:
- case 57:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
pathExpression();
break;
@@ -1842,6 +1912,18 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case MOD:
mod();
break;
+ case YEAR:
+ case MONTH:
+ case WEEK:
+ case DAY_OF_YEAR:
+ case DAY:
+ case DAY_OF_MONTH:
+ case DAY_OF_WEEK:
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ dateTimeExtractingFunction();
+ break;
default:
jj_la1[35] = jj_gen;
jj_consume_token(-1);
@@ -2067,9 +2149,9 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
case ASTERISK:
asterisk();
break;
- case 55:
- case 56:
- case 57:
+ case 65:
+ case 66:
+ case 67:
case PROPERTY_PATH:
pathExpression();
break;
@@ -2290,9 +2372,77 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
}
+/* Date/time parts extracting function */
+ final public void dateTimeExtractingFunction() throws ParseException {
+ /*@bgen(jjtree) #Extract( 1) */
+ ASTExtract jjtn000 = new ASTExtract(JJTEXTRACT);
+ boolean jjtc000 = true;
+ jjtree.openNodeScope(jjtn000);Token t;
+ try {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case YEAR:
+ t = jj_consume_token(YEAR);
+ break;
+ case MONTH:
+ t = jj_consume_token(MONTH);
+ break;
+ case WEEK:
+ t = jj_consume_token(WEEK);
+ break;
+ case DAY_OF_YEAR:
+ t = jj_consume_token(DAY_OF_YEAR);
+ break;
+ case DAY:
+ t = jj_consume_token(DAY);
+ break;
+ case DAY_OF_MONTH:
+ t = jj_consume_token(DAY_OF_MONTH);
+ break;
+ case DAY_OF_WEEK:
+ t = jj_consume_token(DAY_OF_WEEK);
+ break;
+ case HOUR:
+ t = jj_consume_token(HOUR);
+ break;
+ case MINUTE:
+ t = jj_consume_token(MINUTE);
+ break;
+ case SECOND:
+ t = jj_consume_token(SECOND);
+ break;
+ default:
+ jj_la1[40] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ jjtn000.setPartToken(t.image);
+ jj_consume_token(16);
+ pathExpression();
+ jj_consume_token(17);
+ } catch (Throwable jjte000) {
+ if (jjtc000) {
+ jjtree.clearNodeScope(jjtn000);
+ jjtc000 = false;
+ } else {
+ jjtree.popNode();
+ }
+ if (jjte000 instanceof RuntimeException) {
+ {if (true) throw (RuntimeException)jjte000;}
+ }
+ if (jjte000 instanceof ParseException) {
+ {if (true) throw (ParseException)jjte000;}
+ }
+ {if (true) throw (Error)jjte000;}
+ } finally {
+ if (jjtc000) {
+ jjtree.closeNodeScope(jjtn000, 1);
+ }
+ }
+ }
+
final public void namedParameter() throws ParseException {
Token t;
- jj_consume_token(54);
+ jj_consume_token(64);
t = jj_consume_token(PROPERTY_PATH);
ASTNamedParameter jjtn001 = new ASTNamedParameter(JJTNAMEDPARAMETER);
boolean jjtc001 = true;
@@ -2326,8 +2476,8 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
}
break;
- case 55:
- jj_consume_token(55);
+ case 65:
+ jj_consume_token(65);
t = jj_consume_token(PROPERTY_PATH);
ASTObjPath jjtn002 = new ASTObjPath(JJTOBJPATH);
boolean jjtc002 = true;
@@ -2342,8 +2492,8 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
}
break;
- case 56:
- jj_consume_token(56);
+ case 66:
+ jj_consume_token(66);
t = jj_consume_token(PROPERTY_PATH);
ASTDbPath jjtn003 = new ASTDbPath(JJTDBPATH);
boolean jjtc003 = true;
@@ -2358,8 +2508,8 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
}
break;
- case 57:
- jj_consume_token(57);
+ case 67:
+ jj_consume_token(67);
t = jj_consume_token(PROPERTY_PATH);
ASTScalar jjtn004 = new ASTScalar(JJTSCALAR);
boolean jjtc004 = true;
@@ -2375,7 +2525,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
break;
default:
- jj_la1[40] = jj_gen;
+ jj_la1[41] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -2390,7 +2540,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
public Token jj_nt;
private int jj_ntk;
private int jj_gen;
- final private int[] jj_la1 = new int[41];
+ final private int[] jj_la1 = new int[42];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static private int[] jj_la1_2;
@@ -2400,13 +2550,13 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
jj_la1_init_2();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x2,0x4,0x18,0x16010018,0x60,0x180,0x10000,0x4fff8,0x4fff8,0x16010000,0x18,0x10000,0x4e000,0x80000,0x16010000,0x0,0x0,0x16010000,0x0,0x100000,0x200000,0x400000,0x1800000,0x1800000,0x6000000,0x6000000,0x8000000,0x8000000,0x16010000,0x2000000,0x6010000,0x10000,0x0,0x80000,0x80000,0x0,0x80000,0x0,0x0,0x0,0x0,};
+ jj_la1_0 = new int[] {0x2,0x4,0x18,0x16010018,0x60,0x180,0x10000,0x4fff8,0x4fff8,0x16010000,0x18,0x10000,0x4e000,0x80000,0x16010000,0x0,0x0,0x16010000,0x0,0x100000,0x200000,0x400000,0x1800000,0x1800000,0x6000000,0x6000000,0x8000000,0x8000000,0x16010000,0x2000000,0x6010000,0x10000,0x0,0x80000,0x80000,0x0,0x80000,0x0,0x0,0x0,0x0,0x0,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0xbfffffe,0x0,0x0,0x400000,0x0,0x0,0xbfffffe,0x0,0x400000,0x0,0x0,0xbfffff2,0xb803e00,0x3e00,0xbfffffe,0x40000c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000000,0x4000000,0xbc7c000,0x0,0xbc7c000,0xbc7c000,0x3e00,0x0,0x0,0x7c000,0x0,0x1f0,0xf800000,0x380000,0xb800000,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0xfffffffe,0x0,0x0,0x0,0x0,0x0,0xfffffffe,0x0,0x0,0x0,0x0,0xfffffff2,0x3e00,0x3e00,0xfffffffe,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffc7c000,0x0,0xffc7c000,0xffc7c000,0x3e00,0x0,0x0,0xffc7c000,0x0,0x1f0,0x0,0x380000,0xffc00000,0x0,};
}
private static void jj_la1_init_2() {
- jj_la1_2 = new int[] {0x0,0x0,0x0,0x1c8,0x0,0x0,0x0,0x0,0x0,0x1c8,0x0,0x0,0x0,0x0,0x1c8,0x48,0x48,0x1c8,0x1c8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180,0x0,0x180,0x180,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_2 = new int[] {0x0,0x0,0x0,0x7202f,0x0,0x0,0x1,0x0,0x0,0x7202f,0x0,0x1,0x0,0x0,0x7202f,0x1202e,0x12000,0x7202f,0x72001,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x6002f,0x0,0x6002f,0x6002f,0x0,0x0,0x0,0x0,0x0,0x0,0x3e,0x0,0x0,0x2e,};
}
/** Constructor with InputStream. */
@@ -2420,7 +2570,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 41; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 42; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
@@ -2435,7 +2585,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
jj_ntk = -1;
jjtree.reset();
jj_gen = 0;
- for (int i = 0; i < 41; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 42; i++) jj_la1[i] = -1;
}
/** Constructor. */
@@ -2445,7 +2595,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 41; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 42; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
@@ -2456,7 +2606,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
jj_ntk = -1;
jjtree.reset();
jj_gen = 0;
- for (int i = 0; i < 41; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 42; i++) jj_la1[i] = -1;
}
/** Constructor with generated Token Manager. */
@@ -2465,7 +2615,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 41; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 42; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
@@ -2475,7 +2625,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
jj_ntk = -1;
jjtree.reset();
jj_gen = 0;
- for (int i = 0; i < 41; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 42; i++) jj_la1[i] = -1;
}
private Token jj_consume_token(int kind) throws ParseException {
@@ -2526,12 +2676,12 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
/** Generate ParseException. */
public ParseException generateParseException() {
jj_expentries.clear();
- boolean[] la1tokens = new boolean[77];
+ boolean[] la1tokens = new boolean[87];
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 41; i++) {
+ for (int i = 0; i < 42; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
@@ -2546,7 +2696,7 @@ public class ExpressionParser/*@bgen(jjtree)*/implements ExpressionParserTreeCon
}
}
}
- for (int i = 0; i < 77; i++) {
+ for (int i = 0; i < 87; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
http://git-wip-us.apache.org/repos/asf/cayenne/blob/05a77250/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
index a4c1a77..18c00e2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParserConstants.java
@@ -73,35 +73,55 @@ public interface ExpressionParserConstants {
/** RegularExpression Id. */
int CURRENT_TIMESTAMP = 53;
/** RegularExpression Id. */
- int ASTERISK = 58;
+ int YEAR = 54;
/** RegularExpression Id. */
- int PROPERTY_PATH = 59;
+ int MONTH = 55;
/** RegularExpression Id. */
- int IDENTIFIER = 60;
+ int WEEK = 56;
/** RegularExpression Id. */
- int LETTER = 61;
+ int DAY_OF_YEAR = 57;
/** RegularExpression Id. */
- int DIGIT = 62;
+ int DAY = 58;
/** RegularExpression Id. */
- int ESC = 65;
+ int DAY_OF_MONTH = 59;
/** RegularExpression Id. */
- int SINGLE_QUOTED_STRING = 67;
+ int DAY_OF_WEEK = 60;
/** RegularExpression Id. */
- int STRING_ESC = 68;
+ int HOUR = 61;
/** RegularExpression Id. */
- int DOUBLE_QUOTED_STRING = 70;
+ int MINUTE = 62;
/** RegularExpression Id. */
- int INT_LITERAL = 71;
+ int SECOND = 63;
/** RegularExpression Id. */
- int FLOAT_LITERAL = 72;
+ int ASTERISK = 68;
/** RegularExpression Id. */
- int DEC_FLT = 73;
+ int PROPERTY_PATH = 69;
/** RegularExpression Id. */
- int DEC_DIGITS = 74;
+ int IDENTIFIER = 70;
/** RegularExpression Id. */
- int EXPONENT = 75;
+ int LETTER = 71;
/** RegularExpression Id. */
- int FLT_SUFF = 76;
+ int DIGIT = 72;
+ /** RegularExpression Id. */
+ int ESC = 75;
+ /** RegularExpression Id. */
+ int SINGLE_QUOTED_STRING = 77;
+ /** RegularExpression Id. */
+ int STRING_ESC = 78;
+ /** RegularExpression Id. */
+ int DOUBLE_QUOTED_STRING = 80;
+ /** RegularExpression Id. */
+ int INT_LITERAL = 81;
+ /** RegularExpression Id. */
+ int FLOAT_LITERAL = 82;
+ /** RegularExpression Id. */
+ int DEC_FLT = 83;
+ /** RegularExpression Id. */
+ int DEC_DIGITS = 84;
+ /** RegularExpression Id. */
+ int EXPONENT = 85;
+ /** RegularExpression Id. */
+ int FLT_SUFF = 86;
/** Lexical state. */
int DEFAULT = 0;
@@ -166,6 +186,16 @@ public interface ExpressionParserConstants {
"\"currentDate\"",
"\"currentTime\"",
"<CURRENT_TIMESTAMP>",
+ "\"year\"",
+ "\"month\"",
+ "\"week\"",
+ "\"dayOfYear\"",
+ "\"day\"",
+ "\"dayOfMonth\"",
+ "\"dayOfWeek\"",
+ "\"hour\"",
+ "\"minute\"",
+ "\"second\"",
"\"$\"",
"\"obj:\"",
"\"db:\"",
@@ -178,10 +208,10 @@ public interface ExpressionParserConstants {
"\"\\\'\"",
"\"\\\"\"",
"<ESC>",
- "<token of kind 66>",
+ "<token of kind 76>",
"\"\\\'\"",
"<STRING_ESC>",
- "<token of kind 69>",
+ "<token of kind 79>",
"\"\\\"\"",
"<INT_LITERAL>",
"<FLOAT_LITERAL>",