Author: fancy
Date: Thu Jan 22 17:19:47 2009
New Revision: 736881
URL: http://svn.apache.org/viewvc?rev=736881&view=rev
Log:
OPENJPA-856 JPQ2 JPQL add support for entity type expression
Added:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Type.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/TypeLit.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Type.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/TypeLit.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEntityTypeExpression.java
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractFieldStrategy.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Literal.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/AbstractVal.java
Thu Jan 22 17:19:47 2009
@@ -79,6 +79,11 @@
sql.append("1");
}
+ public void appendType(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql) {
+ sql.append("1");
+ }
+
public void appendSize(Select sel, ExpContext ctx, ExpState state,
SQLBuffer sql) {
sql.append("1");
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/InExpression.java
Thu Jan 22 17:19:47 2009
@@ -91,7 +91,11 @@
public void appendTo(Select sel, ExpContext ctx, ExpState state,
SQLBuffer buf) {
InExpState istate = (InExpState) state;
- _const.calculateValue(sel, ctx, istate.constantState, null, null);
+ if (_val instanceof Type)
+ _const.calculateValue(sel, ctx, istate.constantState, _val,
+ istate.valueState);
+ else
+ _const.calculateValue(sel, ctx, istate.constantState, null, null);
_val.calculateValue(sel, ctx, istate.valueState, null, null);
List list = null;
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
Thu Jan 22 17:19:47 2009
@@ -247,6 +247,10 @@
return new Lit(val, ptype);
}
+ public Literal newTypeLiteral(Object val, int ptype) {
+ return new TypeLit(val, ptype);
+ }
+
public Value getThis() {
return new PCPath(_type);
}
@@ -396,6 +400,10 @@
return new Index((Val) val);
}
+ public Value type(Value val) {
+ return new Type((Val) val);
+ }
+
public Value getObjectId(Value val) {
if (val instanceof Const)
return new ConstGetObjectId((Const) val);
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/PCPath.java
Thu Jan 22 17:19:47 2009
@@ -27,6 +27,7 @@
import org.apache.commons.lang.ObjectUtils;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.schema.Column;
@@ -814,6 +815,33 @@
pstate.field.appendIndex(sql, sel, pstate.joins);;
}
+ public void appendType(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql) {
+ Discriminator disc = null;
+ ClassMapping sup = _class;
+ while (sup.getMappedPCSuperclassMapping() != null)
+ sup = sup.getMappedPCSuperclassMapping();
+
+ disc = sup.getDiscriminator();
+
+ Column[] cols = null;
+ if (disc != null)
+ cols = disc.getColumns();
+ else
+ cols = getColumns(state);
+
+ if (cols == null) {
+ sql.append("1");
+ return;
+ }
+
+ for (int i = 0; i < cols.length; i++) {
+ if (i > 0)
+ sql.append(", ");
+ sql.append(sel.getColumnAlias(cols[i], state.joins));
+ }
+ }
+
public void appendSize(Select sel, ExpContext ctx, ExpState state,
SQLBuffer sql) {
PathExpState pstate = (PathExpState) state;
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java
Thu Jan 22 17:19:47 2009
@@ -22,6 +22,7 @@
import java.util.Map;
import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.Filters;
@@ -82,6 +83,12 @@
return Filters.convert(params[_idx], getType());
}
+ public Object getValue(ExpContext ctx, ExpState state) {
+ ParamExpState pstate = (ParamExpState) state;
+ return (pstate.discValue != null) ? pstate.discValue :
+ getValue(ctx.params);
+ }
+
public Object getSQLValue(Select sel, ExpContext ctx, ExpState state) {
return ((ParamExpState) state).sqlValue;
}
@@ -97,7 +104,10 @@
extends ConstExpState {
public Object sqlValue = null;
- public int otherLength = 1;
+ public int otherLength = 1;
+ public ClassMapping mapping = null;
+ public Discriminator disc = null;
+ public Object discValue = null;
}
public void calculateValue(Select sel, ExpContext ctx, ExpState state,
@@ -108,6 +118,14 @@
if (other != null && !_container) {
pstate.sqlValue = other.toDataStoreValue(sel, ctx, otherState,
val);
pstate.otherLength = other.length(sel, ctx, otherState);
+ if (other instanceof Type) {
+ pstate.mapping = ctx.store.getConfiguration().
+ getMappingRepositoryInstance().getMapping((Class) val,
+ ctx.store.getContext().getClassLoader(), true);
+ pstate.disc = pstate.mapping.getDiscriminator();
+ pstate.discValue = pstate.disc != null ? pstate.disc.getValue()
+ : null;
+ }
} else if (ImplHelper.isManageable(val)) {
ClassMapping mapping = ctx.store.getConfiguration().
getMappingRepositoryInstance().getMapping(val.getClass(),
@@ -125,6 +143,10 @@
if (pstate.otherLength > 1)
sql.appendValue(((Object[]) pstate.sqlValue)[index],
pstate.getColumn(index));
+ else if (pstate.cols != null)
+ sql.appendValue(pstate.sqlValue, pstate.getColumn(index));
+ else if (pstate.discValue != null)
+ sql.appendValue(pstate.discValue);
else
sql.appendValue(pstate.sqlValue, pstate.getColumn(index));
}
Added:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Type.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Type.java?rev=736881&view=auto
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Type.java
(added)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Type.java
Thu Jan 22 17:19:47 2009
@@ -0,0 +1,84 @@
+/*
+ * 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.openjpa.jdbc.kernel.exps;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Discriminator;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * Entity Type expression.
+ *
+ * @author Catalina Wei
+ */
+class Type
+ extends UnaryOp {
+
+ Discriminator _disc = null;
+
+ public Type(Val val) {
+ super(val);
+ setMetaData(val.getMetaData());
+ _disc = ((ClassMapping) getMetaData()).getDiscriminator();
+ }
+
+ public ExpState initialize(Select sel, ExpContext ctx, int flags) {
+ // initialize the value with a null test
+ return initializeValue(sel, ctx, NULL_CMP);
+ }
+
+ public Object load(ExpContext ctx, ExpState state, Result res)
+ throws SQLException {
+ Object type = getValue().load(ctx, state, res);
+ return type.getClass();
+ }
+
+ public void calculateValue(Select sel, ExpContext ctx, ExpState state,
+ Val other, ExpState otherState) {
+ super.calculateValue(sel, ctx, state, null, null);
+ if (_disc != null)
+ _disc.select(sel, (ClassMapping) getMetaData());
+ }
+
+ public void select(Select sel, ExpContext ctx, ExpState state,
+ boolean pks) {
+ getValue().select(sel, ctx, state, pks);
+ }
+
+ public void appendTo(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql, int index) {
+ getValue().calculateValue(sel, ctx, state, null, null);
+ getValue().appendType(sel, ctx, state, sql);
+ sel.append(sql, state.joins);
+ }
+
+ protected Class getType(Class c) {
+ return Class.class;
+ }
+
+ protected String getOperator() {
+ // since we override appendTo(), this method should never be called
+ throw new InternalException();
+ }
+}
Added:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/TypeLit.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/TypeLit.java?rev=736881&view=auto
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/TypeLit.java
(added)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/TypeLit.java
Thu Jan 22 17:19:47 2009
@@ -0,0 +1,127 @@
+/*
+ * 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.openjpa.jdbc.kernel.exps;
+
+import org.apache.openjpa.jdbc.meta.ClassMapping;
+import org.apache.openjpa.jdbc.meta.Discriminator;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.exps.Literal;
+import org.apache.openjpa.meta.JavaTypes;
+
+/**
+ * A type literal value.
+ *
+ * @author Catalina Wei
+ */
+public class TypeLit
+ extends Const
+ implements Literal {
+
+ private Object _val;
+ private int _ptype;
+
+ /**
+ * Constructor. Supply literal value.
+ */
+ public TypeLit(Object val, int ptype) {
+ _val = val;
+ _ptype = ptype;
+ }
+
+ public Class getType() {
+ return (_val == null) ? Object.class : _val.getClass();
+ }
+
+ public void setImplicitType(Class type) {
+ _val = Filters.convert(_val, type);
+ }
+
+ public int getParseType() {
+ return _ptype;
+ }
+
+ public Object getValue() {
+ return _val;
+ }
+
+ public void setValue(Object val) {
+ _val = val;
+ }
+
+ public Object getValue(Object[] params) {
+ return getValue();
+ }
+
+ public ExpState initialize(Select sel, ExpContext ctx, int flags) {
+ return new LitExpState();
+ }
+
+ /**
+ * Expression state.
+ */
+ private static class LitExpState
+ extends ConstExpState {
+
+ public Object sqlValue;
+ public int otherLength;
+ public ClassMapping mapping = null;
+ public Discriminator disc = null;
+ public Object discValue = null;
+ }
+
+ public void calculateValue(Select sel, ExpContext ctx, ExpState state,
+ Val other, ExpState otherState) {
+ super.calculateValue(sel, ctx, state, other, otherState);
+ LitExpState lstate = (LitExpState) state;
+ lstate.mapping = (ClassMapping) getMetaData();
+ lstate.disc = lstate.mapping.getDiscriminator();
+ lstate.discValue = lstate.disc != null ? lstate.disc.getValue() :
+ null;
+ sel.select(((ClassMapping) getMetaData()).getPrimaryKeyColumns(),
+ lstate.joins);
+ }
+
+ public void appendTo(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql, int index) {
+ LitExpState lstate = (LitExpState) state;
+ if (lstate.otherLength > 1)
+ sql.appendValue(((Object[]) lstate.sqlValue)[index],
+ lstate.getColumn(index));
+ else {
+ if (lstate.discValue != null)
+ sql.append(getDiscriminator(lstate));
+ else
+ sql.append("1");
+ }
+ }
+
+ private String getDiscriminator(LitExpState lstate) {
+ StringBuffer disc = new StringBuffer(lstate.discValue.toString());
+ switch(lstate.disc.getJavaType()) {
+ case JavaTypes.INT:
+ return disc.toString();
+ case JavaTypes.CHAR:
+ case JavaTypes.STRING:
+ default:
+ return disc.insert(0, "'").append("'").toString();
+ }
+ }
+}
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
Thu Jan 22 17:19:47 2009
@@ -153,6 +153,12 @@
SQLBuffer sql);
/**
+ * Append the SQL checking the type of this value.
+ */
+ public void appendType(Select sel, ExpContext ctx, ExpState state,
+ SQLBuffer sql);
+
+ /**
* Append the SQL checking the size of this value.
*/
public void appendSize(Select sel, ExpContext ctx, ExpState state,
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldMapping.java
Thu Jan 22 17:19:47 2009
@@ -862,6 +862,10 @@
assertStrategy().appendIndex(sql, sel, joins);
}
+ public void appendType(SQLBuffer sql, Select sel, Joins joins) {
+ assertStrategy().appendType(sql, sel, joins);
+ }
+
public Joins join(Joins joins, boolean forceOuter) {
return assertStrategy().join(joins, forceOuter);
}
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/FieldStrategy.java
Thu Jan 22 17:19:47 2009
@@ -186,6 +186,11 @@
public void appendIndex(SQLBuffer sql, Select sel, Joins joins);
/**
+ * Append the entity discriminator value to the given statement.
+ */
+ public void appendType(SQLBuffer sql, Select sel, Joins joins);
+
+ /**
* Join this value to the class table. Does nothing by default.
*/
public Joins join(Joins joins, boolean forceOuter);
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractFieldStrategy.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractFieldStrategy.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractFieldStrategy.java
(original)
+++
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/AbstractFieldStrategy.java
Thu Jan 22 17:19:47 2009
@@ -139,6 +139,10 @@
sql.append("1");
}
+ public void appendType(SQLBuffer sql, Select sel, Joins joins) {
+ sql.append("1");
+ }
+
public Joins join(Joins joins, boolean forceOuter) {
return joins;
}
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
Thu Jan 22 17:19:47 2009
@@ -403,6 +403,13 @@
public Value index(Value target);
/**
+ * Return the type/class of the given value.
+ *
+ * @since 2.0.0
+ */
+ public Value type(Value target);
+
+ /**
* Return distinct values of the given value. This is typically used
* within aggregates, for example: max(distinct(path))
*
@@ -445,4 +452,10 @@
* Return a nullif expression
*/
public Value nullIfExpression(Value val1, Value val2);
+
+ /**
+ * Return a value representing the given constant, which will be
+ * a {...@link Number}, {...@link String}, or {...@link Boolean} instance.
+ */
+ public Literal newTypeLiteral(Object val, int parseType);
}
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
Thu Jan 22 17:19:47 2009
@@ -480,6 +480,10 @@
return new Lit(val, parseType);
}
+ public Literal newTypeLiteral(Object val, int parseType) {
+ return new TypeLit(val, parseType);
+ }
+
public Value getThis() {
return new This();
}
@@ -635,6 +639,10 @@
return new Index((Val) val);
}
+ public Value type(Value val) {
+ return new Type((Val) val);
+ }
+
public Value getObjectId(Value val) {
return new GetObjectId((Val) val);
}
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Literal.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Literal.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Literal.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Literal.java
Thu Jan 22 17:19:47 2009
@@ -32,6 +32,7 @@
public static final int TYPE_BOOLEAN = 2;
public static final int TYPE_STRING = 3;
public static final int TYPE_SQ_STRING = 4; // single-quoted string
+ public static final int TYPE_CLASS = 5;
/**
* The value of this literal.
Added:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Type.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Type.java?rev=736881&view=auto
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Type.java
(added)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Type.java
Thu Jan 22 17:19:47 2009
@@ -0,0 +1,63 @@
+/*
+ * 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.openjpa.kernel.exps;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.openjpa.kernel.StoreContext;
+
+import serp.util.Numbers;
+
+/**
+ * Returns the entity type.
+ *
+ * @author Catalina Wei
+ */
+class Type extends Val {
+
+ private final Val _val;
+
+ /**
+ * Constructor. Provide target string and the arguments to the
+ * indexOf method.
+ */
+ public Type(Val val) {
+ _val = val;
+ }
+
+ public Class getType() {
+ return Class.class;
+ }
+
+ public void setImplicitType(Class type) {
+ }
+
+ protected Object eval(Object candidate, Object orig,
+ StoreContext ctx, Object[] params) {
+ _val.eval(candidate, orig, ctx, params);
+ return _val.getType();
+ }
+
+ public void acceptVisit(ExpressionVisitor visitor) {
+ visitor.enter(this);
+ _val.acceptVisit(visitor);
+ visitor.exit(this);
+ }
+}
Added:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/TypeLit.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/TypeLit.java?rev=736881&view=auto
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/TypeLit.java
(added)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/TypeLit.java
Thu Jan 22 17:19:47 2009
@@ -0,0 +1,72 @@
+/*
+ * 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.openjpa.kernel.exps;
+
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.StoreContext;
+
+/**
+ * Represents a type literal.
+ *
+ * @author Catalina Wei
+ */
+class TypeLit
+ extends Val
+ implements Literal {
+
+ private Object _val;
+ private final int _ptype;
+
+ /**
+ * Constructor. Provide constant value.
+ */
+ public TypeLit(Object val, int ptype) {
+ _val = val;
+ _ptype = ptype;
+ }
+
+ public Object getValue() {
+ return _val;
+ }
+
+ public void setValue(Object val) {
+ _val = val;
+ }
+
+ public int getParseType() {
+ return _ptype;
+ }
+
+ public Object getValue(Object[] parameters) {
+ return _val;
+ }
+
+ public Class getType() {
+ return (_val == null) ? Object.class : _val.getClass();
+ }
+
+ public void setImplicitType(Class type) {
+ _val = Filters.convert(_val, type);
+ }
+
+ protected Object eval(Object candidate, Object orig,
+ StoreContext ctx, Object[] params) {
+ return _val;
+ }
+}
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
Thu Jan 22 17:19:47 2009
@@ -330,14 +330,23 @@
if (aliasNode != null)
proj.setAlias(alias);
exps.projections[i] = proj;
- exps.projectionClauses[i] = aliasNode == null ?
- assemble(node.id == JJTSCALAREXPRESSION ? firstChild(node)
- : node) : alias;
+ exps.projectionClauses[i] = aliasNode != null ? alias :
+ projectionClause(node.id == JJTSCALAREXPRESSION ?
+ firstChild(node) : node);
exps.projectionAliases[i] = alias;
}
return exp;
}
+ private String projectionClause(JPQLNode node) {
+ switch (node.id) {
+ case JJTTYPE:
+ return projectionClause(firstChild(node));
+ default:
+ return assemble(node);
+ }
+ }
+
private void evalQueryOperation(QueryExpressions exps) {
// determine whether we want to select, delete, or update
if (root().id == JJTSELECT || root().id == JJTSUBSELECT)
@@ -746,7 +755,10 @@
return eval(onlyChild(node));
case JJTTYPE:
- return eval(onlyChild(node));
+ return getType(onlyChild(node));
+
+ case JJTTYPELITERAL:
+ return getTypeLiteral(node);
case JJTCLASSNAME:
return getPathOrConstant(node);
@@ -754,10 +766,10 @@
case JJTCASE:
return eval(onlyChild(node));
- case JJTSCASE:
+ case JJTSIMPLECASE:
return getSimpleCaseExpression(node);
- case JJTGCASE:
+ case JJTGENERALCASE:
return getGeneralCaseExpression(node);
case JJTWHEN:
@@ -814,6 +826,10 @@
case JJTPOSITIONALINPUTPARAMETER:
return getParameter(node.text, true);
+ case JJTCOLLECTIONPARAMETER:
+ // TODO: support collection valued parameters
+ return getParameter(onlyChild(node).text, true);
+
case JJTOR: // x OR y
return factory.or(getExpression(left(node)),
getExpression(right(node)));
@@ -892,14 +908,19 @@
factory.lessThanEqual(val1, val3)));
case JJTIN: // x.field [NOT] IN ('a', 'b', 'c')
-
+ // TYPE(x...) [NOT] IN (entityTypeLiteral1,...)
Expression inExp = null;
Iterator inIterator = node.iterator();
// the first child is the path
- val1 = getValue((JPQLNode) inIterator.next());
+ JPQLNode first = (JPQLNode) inIterator.next();
+ val1 = getValue(first);
while (inIterator.hasNext()) {
- val2 = getValue((JPQLNode) inIterator.next());
+ JPQLNode next = (JPQLNode) inIterator.next();
+ if (first.id == JJTTYPE && next.id == JJTTYPELITERAL)
+ val2 = getTypeLiteral(next);
+ else
+ val2 = getValue(next);
// special case for <value> IN (<subquery>) or
// <value> IN (<single value>)
@@ -1360,6 +1381,21 @@
} else if (val instanceof Path) {
return (Path) val;
} else if (val instanceof Value) {
+ if (val.isVariable()) {
+ // can be an entity type literal
+ Class c = resolver.classForName(name, null);
+ if (c != null) {
+ Value lit = factory.newTypeLiteral(c, Literal.TYPE_CLASS);
+ Class<?> candidate = getCandidateType();
+ ClassMetaData can = getClassMetaData(candidate.getName(),
false);
+ ClassMetaData meta = getClassMetaData(name, false);
+ if (candidate.isAssignableFrom(c))
+ lit.setMetaData(meta);
+ else
+ lit.setMetaData(can);
+ return lit;
+ }
+ }
return (Value) val;
}
@@ -1367,6 +1403,24 @@
new Object[]{ name }, null);
}
+ private Value getTypeLiteral(JPQLNode node) {
+ JPQLNode type = onlyChild(node);
+ final String name = type.text;
+ final Value val = getVariable(name, false);
+
+ if (val instanceof Value && val.isVariable()) {
+ Class c = resolver.classForName(name, null);
+ if (c != null) {
+ Value typeLit = factory.newTypeLiteral(c, Literal.TYPE_CLASS);
+ typeLit.setMetaData(getClassMetaData(name, false));
+ return typeLit;
+ }
+ }
+
+ throw parseException(EX_USER, "not-type-literal",
+ new Object[]{ name }, null);
+ }
+
private Value getPathOrConstant(JPQLNode node) {
// first check to see if the path is an enum or static field, and
// if so, load it
@@ -1394,6 +1448,36 @@
}
}
+ /**
+ * Process type_discriminator
+ * type_discriminator ::=
+ * TYPE(identification_variable |
+ * single_valued_object_path_expression |
+ * input_parameter )
+ */
+ private Value getType(JPQLNode node) {
+ switch (node.id) {
+ case JJTIDENTIFIER:
+ return factory.type(getValue(node));
+
+ case JJTNAMEDINPUTPARAMETER:
+ return factory.type(getParameter(node.text, false));
+
+ case JJTPOSITIONALINPUTPARAMETER:
+ return factory.type(getParameter(node.text, true));
+
+ default:
+ // TODO: enforce jpa2.0 spec rules.
+ // A single_valued_object_field is designated by the name of
+ // an association field in a one-to-one or many-to-one relationship
+ // or a field of embeddable class type.
+ // The type of a single_valued_object_field is the abstract schema
+ // type of the related entity or embeddable class
+ Value path = getPath(node, false, true);
+ return factory.type(path);
+ }
+ }
+
private Path getPath(JPQLNode node) {
return getPath(node, false, true);
}
Modified:
openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
Thu Jan 22 17:19:47 2009
@@ -745,19 +745,26 @@
void in_expression() #IN : { }
{
- (path() | scalar_function()) [ LOOKAHEAD(1) <NOT> { jjtThis.not = true;
}] <IN>
- "(" (literal_or_param()
+ (path() | scalar_function() | type_discriminator()) [ LOOKAHEAD(1)
<NOT> { jjtThis.not = true; }] <IN>
+ ("(" (literal_or_param()
(<COMMA> (literal_or_param()))* | subquery())
- ")"
+ ")"
+ | collection_valued_input_parameter()
+ )
}
+void entity_type_literal() #TYPELITERAL : { }
+{
+ identification_variable()
+}
void literal_or_param() : { }
{
(numeric_literal()
| string_literal()
| boolean_literal()
- | input_parameter())
+ | input_parameter()
+ | entity_type_literal())
}
@@ -941,46 +948,51 @@
LOOKAHEAD(2) "(" arithmetic_expression() ")" |
functions_returning_numerics() |
aggregate_select_expression() |
+ LOOKAHEAD(case_expression()) case_expression() |
subquery()
}
-void qualified_path() #QPATH : { }
+void qualified_path() #QUALIFIEDPATH : { }
{
general_identification_variable() (LOOKAHEAD(2) <DOT> path_component())+
}
-void qualified_identification_variable() #QIDENTIFIER : { }
+void qualified_identification_variable() #QUALIFIEDIDENTIFIER : { }
{
- ( <KEY> "(" identification_variable() ")" #KEY
- | <VALUE> "(" identification_variable() ")" #VALUE
- | <ENTRY> "(" identification_variable() ")" #ENTRY
+ ( <KEY> "(" identification_variable() ")" #KEY(1)
+ | <VALUE> "(" identification_variable() ")" #VALUE(1)
+ | <ENTRY> "(" identification_variable() ")" #ENTRY(1)
)
}
-void general_identification_variable() #GIDENTIFIER : { }
+void general_identification_variable() #GENERALIDENTIFIER : { }
{
- ( <KEY> "(" identification_variable() ")" #KEY
- | <VALUE> "(" identification_variable() ")" #VALUE
+ ( <KEY> "(" identification_variable() ")" #KEY(1)
+ | <VALUE> "(" identification_variable() ")" #VALUE(1)
)
}
void entity_type_comp() : { }
{
- entity_type_expression()
- ( <EQ> entity_type_expression() #EQUALS(2)
- | <NE> entity_type_expression() #NOTEQUALS(2)
+ (entity_type_expression() | entity_type_literal())
+ ( <EQ> (entity_type_expression() | entity_type_literal()) #EQUALS(2)
+ | <NE> (entity_type_expression() | entity_type_literal()) #NOTEQUALS(2)
)
}
-void entity_type_expression() #TYPE : { }
+void type_discriminator() #TYPE : { }
{
- <TYPE> "(" (LOOKAHEAD(identification_variable()) identification_variable()
- | LOOKAHEAD(path()) path()
+ <TYPE> "(" (LOOKAHEAD(path()) path()
| LOOKAHEAD(general_identification_variable())
general_identification_variable()
+ | LOOKAHEAD(identification_variable()) identification_variable()
| LOOKAHEAD(input_parameter()) input_parameter())
- ")" |
- classname() #TYPE_LITERAL |
+ ")"
+}
+
+void entity_type_expression(): { }
+{
+ type_discriminator() |
input_parameter()
}
@@ -990,7 +1002,7 @@
LOOKAHEAD(case_expression()) case_expression() |
LOOKAHEAD(string_primary()) string_primary() |
LOOKAHEAD(datetime_primary()) datetime_primary() |
- LOOKAHEAD(enum_primary()) enum_primary()
+ LOOKAHEAD(enum_primary()) enum_primary() |
LOOKAHEAD(entity_type_expression()) entity_type_expression()
}
@@ -1004,29 +1016,31 @@
<NULLIF> nullif_expression()
}
-void general_case_expression() #GCASE : { }
+void general_case_expression() #GENERALCASE : { }
{
(when_clause())+
- <ELSE> scalar_expression()
+ <ELSE> (LOOKAHEAD(2) scalar_expression() | entity_type_literal())
<END>
}
void when_clause() #WHEN : { }
{
- <WHEN> conditional_expression() <THEN> scalar_expression()
+ <WHEN> conditional_expression()
+ <THEN> (LOOKAHEAD(2) scalar_expression() | entity_type_literal())
}
-void simple_case_expression() #SCASE : { }
+void simple_case_expression() #SIMPLECASE : { }
{
- (LOOKAHEAD(2) path() | entity_type_expression())
+ (LOOKAHEAD(type_discriminator()) type_discriminator() | LOOKAHEAD(path())
path())
(simple_when_clause())+
- <ELSE> scalar_expression()
+ <ELSE> (LOOKAHEAD(2) scalar_expression() | entity_type_literal())
<END>
}
void simple_when_clause() #WHENSCALAR : { }
{
- <WHEN> scalar_expression() <THEN> scalar_expression()
+ <WHEN> (LOOKAHEAD(2) scalar_expression() | entity_type_literal())
+ <THEN> (LOOKAHEAD(2) scalar_expression() | entity_type_literal())
}
void coalesce_expression() #COALESCE : { }
@@ -1409,6 +1423,12 @@
}
+void collection_valued_input_parameter() #COLLECTIONPARAMETER: { }
+{
+ named_input_parameter() | positional_input_parameter()
+}
+
+
void named_input_parameter() #NAMEDINPUTPARAMETER :
{ Token t; }
{
Modified:
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
Thu Jan 22 17:19:47 2009
@@ -71,4 +71,5 @@
openjpa.Compatibility configuration setting is configured to disallow \
JPQL extensions.
jpql-parse-error: "{1}" while parsing JPQL "{0}". See nested stack trace for \
- original parse error.
\ No newline at end of file
+ original parse error.
+not-type-literal: The specified node ("{0}") is not a valid entity type
literal.
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEntityTypeExpression.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEntityTypeExpression.java?rev=736881&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEntityTypeExpression.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestEntityTypeExpression.java
Thu Jan 22 17:19:47 2009
@@ -0,0 +1,192 @@
+/*
+ * 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.openjpa.persistence.jpql.expressions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.persistence.common.apps.*;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+public class TestEntityTypeExpression extends AbstractTestCase {
+
+ private int userid1, userid2, userid3, userid4, userid5, userid6;
+
+ public TestEntityTypeExpression(String name) {
+ super(name, "jpqlclausescactusapp");
+ }
+
+ public void setUp() {
+ deleteAll(CompUser.class);
+ EntityManager em = currentEntityManager();
+ startTx(em);
+
+ Address[] add = new Address[]{
+ new Address("43 Sansome", "SF", "United-Kingdom", "94104"),
+ new Address("24 Mink", "ANTIOCH", "USA", "94513"),
+ new Address("23 Ogbete", "CoalCamp", "NIGERIA", "00000"),
+ new Address("10 Wilshire", "Worcester", "CANADA", "80080"),
+ new Address("23 Bellflower", "Ogui", null, "02000"),
+ new Address("22 Montgomery", "SF", null, "50054") };
+
+ CompUser user1 = createUser("Seetha", "MAC", add[0], 36, true);
+ CompUser user2 = createUser("Shannon ", "PC", add[1], 36, false);
+ CompUser user3 = createUser("Ugo", "PC", add[2], 19, true);
+ CompUser user4 = createUser("_Jacob", "LINUX", add[3], 10, true);
+ CompUser user5 = createUser("Famzy", "UNIX", add[4], 29, false);
+ CompUser user6 = createUser("Shade", "UNIX", add[5], 23, false);
+
+ em.persist(user1);
+ userid1 = user1.getUserid();
+ em.persist(user2);
+ userid2 = user2.getUserid();
+ em.persist(user3);
+ userid3 = user3.getUserid();
+ em.persist(user4);
+ userid4 = user4.getUserid();
+ em.persist(user5);
+ userid5 = user5.getUserid();
+ em.persist(user6);
+ userid6 = user6.getUserid();
+
+ endTx(em);
+ endEm(em);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testTypeExpression() {
+ EntityManager em = currentEntityManager();
+
+ String query = null;
+ List<CompUser> rs = null;
+ CompUser user = null;
+
+// TODO: test when support for collection valued parameters is available
+// Collection params = new ArrayList();
+// params.add(FemaleUser.class);
+// params.add(MaleUser.class);
+// query = "SELECT e FROM CompUser e where TYPE(e) = :params";
+// rs = em.createQuery(query).
+// setParameter("params", params).getResultList();
+// user = rs.get(0);
+// assertEquals("the name is not shannon", "Shannon ", user.getName());
+
+ query = "SELECT TYPE(e) FROM MaleUser e where TYPE(e) = MaleUser";
+ rs = em.createQuery(query).getResultList();
+ Object type = rs.get(0);
+ assertEquals(type, MaleUser.class);
+
+ query = "SELECT TYPE(e) FROM CompUser e where TYPE(e) = ?1";
+ rs = em.createQuery(query).
+ setParameter(1, FemaleUser.class).getResultList();
+ type = rs.get(0);
+ assertEquals(type, FemaleUser.class);
+
+ query = "SELECT TYPE(e) FROM MaleUser e where TYPE(e) = ?1";
+ rs = em.createQuery(query).
+ setParameter(1, MaleUser.class).getResultList();
+ type = rs.get(0);
+ assertEquals(type, MaleUser.class);
+
+ query = "SELECT e, FemaleUser, a FROM Address a, FemaleUser e " +
+ " where e.address IS NOT NULL";
+ List<Object> rs2 = em.createQuery(query).getResultList();
+ type = ((Object[]) rs2.get(0))[1];
+ assertEquals(type, FemaleUser.class);
+
+ query = "SELECT e FROM CompUser e where TYPE(e) = :typeName";
+ rs = em.createQuery(query).
+ setParameter("typeName", FemaleUser.class).getResultList();
+ user = rs.get(0);
+ assertEquals("the name is not shannon", "Shannon ", user.getName());
+
+ query = "SELECT e FROM CompUser e where TYPE(e) = ?1";
+ rs = em.createQuery(query).
+ setParameter(1, FemaleUser.class).getResultList();
+ user = rs.get(0);
+ assertEquals("the name is not shannon", "Shannon ", user.getName());
+
+ query = "SELECT e FROM CompUser e where TYPE(e) in (?1)";
+ rs = em.createQuery(query).
+ setParameter(1, MaleUser.class).getResultList();
+ user = rs.get(0);
+ assertEquals(user.getName(), "Seetha");
+
+ query = "SELECT e FROM CompUser e where TYPE(e) in (?1, ?2)";
+ rs = em.createQuery(query).
+ setParameter(1, FemaleUser.class).setParameter(2, MaleUser.class).
+ getResultList();
+ user = rs.get(0);
+ assertEquals("the name is not shannon", "Shannon ", user.getName());
+
+ query = "select sum(e.age) FROM CompUser e GROUP BY e.age" +
+ " HAVING ABS(e.age) = :param";
+ Long sum = (Long) em.createQuery(query).
+ setParameter("param", new Double(36)).getSingleResult();
+ assertEquals(sum.intValue(), 72);
+
+ String[] queries = {
+ "SELECT e FROM CompUser e where TYPE(e) = MaleUser",
+ "SELECT e from CompUser e where TYPE(e) in (FemaleUser)",
+ "SELECT e from CompUser e where TYPE(e) not in (FemaleUser)",
+ "SELECT e from CompUser e where TYPE(e) in (MaleUser, FemaleUser)",
+ "SELECT TYPE(e) FROM CompUser e where TYPE(e) = MaleUser",
+ "SELECT TYPE(e) FROM CompUser e",
+ "SELECT TYPE(a.user) FROM Address a",
+ "SELECT MaleUser FROM CompUser e",
+ "SELECT MaleUser FROM Address a",
+ "SELECT " +
+ " CASE TYPE(e) WHEN FemaleUser THEN 'Female' " +
+ " ELSE 'Male' " +
+ " END " +
+ " FROM CompUser e",
+ };
+
+ for (int i = 0; i < queries.length; i++) {
+ query = queries[i];
+ List<Object> rs1 = em.createQuery(query).getResultList();
+ Object obj = rs1.get(0);
+ obj.toString();
+ System.err.println(obj+" rs size="+rs1.size());
+ }
+
+ endEm(em);
+ }
+
+ public CompUser createUser(String name, String cName, Address add, int age,
+ boolean isMale) {
+ CompUser user = null;
+ if (isMale) {
+ user = new MaleUser();
+ user.setName(name);
+ user.setComputerName(cName);
+ user.setAddress(add);
+ user.setAge(age);
+ } else {
+ user = new FemaleUser();
+ user.setName(name);
+ user.setComputerName(cName);
+ user.setAddress(add);
+ user.setAge(age);
+ }
+ return user;
+ }
+}
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java?rev=736881&r1=736880&r2=736881&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java
Thu Jan 22 17:19:47 2009
@@ -69,11 +69,11 @@
endEm(em);
}
+ @SuppressWarnings("unchecked")
public void testCoalesceExpressions() {
EntityManager em = currentEntityManager();
startTx(em);
-
String query = "SELECT e.name, " +
"COALESCE (e.address.country, 'Unknown')" +
" FROM CompUser e";
@@ -86,6 +86,7 @@
endEm(em);
}
+ @SuppressWarnings("unchecked")
public void testNullIfExpressions() {
EntityManager em = currentEntityManager();
startTx(em);
@@ -103,6 +104,7 @@
endEm(em);
}
+ @SuppressWarnings("unchecked")
public void testSimpleCaseExpressions() {
EntityManager em = currentEntityManager();
@@ -129,15 +131,23 @@
Object[] result2 = (Object[]) rs2.get(rs2.size()-1);
assertEquals("the name is not seetha", "Seetha", result2[0]);
- // TODO: needs entity-type-expression
String query3 = "SELECT e.name, " +
" CASE TYPE(e) WHEN FemaleUser THEN 'Female' " +
" ELSE 'Male' " +
- " END " +
+ " END as result" +
" FROM CompUser e";
+ List rs3 = em.createQuery(query3).getResultList();
+ Object[] result3 = (Object[]) rs3.get(rs3.size()-1);
+ assertEquals("the result is not female", "Female", result3[1]);
+ assertEquals("the name is not shade", "Shade", result3[0]);
+ result3 = (Object[]) rs3.get(0);
+ assertEquals("the result is not male", "Male", result3[1]);
+ assertEquals("the name is not seetha", "Seetha", result3[0]);
+
endEm(em);
}
+ @SuppressWarnings("unchecked")
public void testGeneralCaseExpressions() {
EntityManager em = currentEntityManager();
startTx(em);
@@ -154,7 +164,6 @@
" FROM CompUser e ORDER BY cage";
List rs = em.createQuery(query).getResultList();
-
String update = "UPDATE CompUser e SET e.age = " +
"CASE WHEN e.age > 30 THEN e.age - 1 " +
@@ -169,6 +178,7 @@
endEm(em);
}
+ @SuppressWarnings("unchecked")
public void testMathFuncOrderByAlias() {
EntityManager em = currentEntityManager();