OPENJPA-1309 DB2 requires CAST for argument passed to datastore MOD function

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@816737 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Catalina Wei 2009-09-18 18:38:00 +00:00
parent 1c0b9849f1
commit 3f43e3dd0e
10 changed files with 62 additions and 11 deletions

View File

@ -18,6 +18,8 @@
*/
package org.apache.openjpa.jdbc.kernel.exps;
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.kernel.exps.Arguments;
/**
@ -41,4 +43,20 @@ public class DatastoreFunction extends UnaryOp {
return _functionName;
}
public void appendTo(Select sel, ExpContext ctx, ExpState state,
SQLBuffer sql, int index) {
Args args = (Args) getValue();
if (!ctx.store.getDBDictionary().requiresCastForMathFunctions || args.getValues().length == 1)
super.appendTo(sel, ctx, state, sql, index);
else {
sql.append(getOperator());
sql.append("(");
args.appendTo(sel, ctx, state, sql, 0);
Val[] vals = args.getVals();
for (int i = 1; i < vals.length; i++) {
sql.addCastForParam(getOperator(), vals[i]);
}
sql.append(")");
}
}
}

View File

@ -203,5 +203,9 @@ class EndsWithExpression
public XMLMetaData getXmlMapping() {
return null;
}
public boolean requiresCast() {
return false;
}
}
}

View File

@ -116,4 +116,10 @@ public interface FilterValue {
* else return null;
*/
public XMLMetaData getXmlMapping();
/**
* return true if CAST is required for this filter value
* else return false.
*/
public boolean requiresCast();
}

View File

@ -110,4 +110,8 @@ class FilterValueImpl
public XMLMetaData getXmlMapping() {
return (getXPath() == null) ? null : getXPath().getXmlMapping();
}
public boolean requiresCast() {
return !(_val instanceof All || _val instanceof Any || _val instanceof PCPath);
}
}

View File

@ -194,6 +194,10 @@ class StartsWithExpression
return null;
}
public boolean requiresCast() {
return false;
}
}
/**
@ -278,5 +282,9 @@ class StartsWithExpression
public XMLMetaData getXmlMapping() {
return null;
}
public boolean requiresCast() {
return false;
}
}
}

View File

@ -2784,7 +2784,7 @@ public class DBDictionary
Class rc = Filters.wrap(rhs.getType());
int type = 0;
if (requiresCastForMathFunctions && (lc != rc
|| (lhs.isConstant() && rhs.isConstant()))) {
|| (lhs.isConstant() || rhs.isConstant()))) {
Class c = Filters.promote(lc, rc);
type = getJDBCType(JavaTypes.getTypeCode(c), false);
if (type != Types.VARBINARY && type != Types.BLOB) {
@ -2848,6 +2848,8 @@ public class DBDictionary
if (type != Types.VARBINARY && type != Types.BLOB) {
castlhs = (lhs.isConstant() && rhs.isConstant()) || lc != c;
castrhs = (lhs.isConstant() && rhs.isConstant()) || rc != c;
castlhs = castlhs && lhs.requiresCast();
castrhs = castrhs && rhs.requiresCast();
}
}

View File

@ -357,7 +357,8 @@ public class ResultSetResult
if (metaTypeCode == -1 && obj instanceof Column)
metaTypeCode = ((Column) obj).getJavaType();
boolean isClob = (obj instanceof Column) ? ((Column) obj).getType() == Types.CLOB : false;
boolean isClob = (obj instanceof Column) ? ((Column) obj).getType() == Types.CLOB && !((Column) obj).isXML()
: false;
obj = translate(obj, joins);
Object val = null;

View File

@ -52,6 +52,10 @@ public abstract class AbstractCriteriaTestCase extends TestCase {
protected abstract EntityManager getEntityManager();
private DBDictionary dict = null;
public DBDictionary getDictionary() {
return dict;
}
/**
* Create an entity manager factory for persistence unit <code>pu</code>. Put {@link #CLEAR_TABLES} in this list to
* tell the test framework to delete all table contents before running the tests.
@ -86,8 +90,10 @@ public abstract class AbstractCriteriaTestCase extends TestCase {
void setDictionary() {
JDBCConfiguration conf = (JDBCConfiguration) getEntityManagerFactory().getConfiguration();
dict = conf.getDBDictionaryInstance();
dict.requiresCastForComparisons = false;
dict.requiresCastForMathFunctions = false;
if (dict instanceof DerbyDictionary) {
dict.requiresCastForComparisons = false;
dict.requiresCastForMathFunctions = false;
}
}
/**
@ -174,6 +180,9 @@ public abstract class AbstractCriteriaTestCase extends TestCase {
cSQL.size());
}
if (!(dict instanceof DerbyDictionary))
return;
for (int i = 0; i < jSQL.size(); i++) {
if (!jSQL.get(i).equals(cSQL.get(i))) {
printSQL("Target SQL for JPQL", jSQL);
@ -183,9 +192,6 @@ public abstract class AbstractCriteriaTestCase extends TestCase {
}
}
if (!(dict instanceof DerbyDictionary))
return;
if (expectedSQL != null) {
assertEquals("SQL for JPQL and ExpectedSQL for " + jpql + " is different", jSQL.get(0),
expectedSQL);

View File

@ -54,8 +54,8 @@ public abstract class CriteriaTest extends AbstractCriteriaTestCase {
auditor = new SQLAuditor();
setEntityManagerFactory(createNamedEMF(getDomainClasses()));
assertNotNull(getEntityManagerFactory());
setDictionary();
}
setDictionary();
em = getEntityManagerFactory().createEntityManager();
cb = getEntityManagerFactory().getQueryBuilder();
}

View File

@ -22,10 +22,10 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.metamodel.Attribute;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.sql.DB2Dictionary;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.OracleDictionary;
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.criteria.AbstractCriteriaTestCase.SQLAuditor;
/**
* Tests different styles for query by example.
@ -34,7 +34,7 @@ import org.apache.openjpa.persistence.criteria.AbstractCriteriaTestCase.SQLAudit
*
*/
public class TestQueryByExample extends CriteriaTest {
DBDictionary dict = null;
public void setUp() {
super.setUp();
@ -42,7 +42,7 @@ public class TestQueryByExample extends CriteriaTest {
// comparison of SQL. This may not work on Oracle JDBC drivers
// prior to 10.x
OpenJPAEntityManagerSPI ojem = (OpenJPAEntityManagerSPI)em;
DBDictionary dict = ((JDBCConfiguration) ojem.getConfiguration())
dict = ((JDBCConfiguration) ojem.getConfiguration())
.getDBDictionaryInstance();
if (dict instanceof OracleDictionary) {
dict.setJoinSyntax("sql92");
@ -184,6 +184,8 @@ public class TestQueryByExample extends CriteriaTest {
em.createQuery(q).getResultList();
assertEquals(1,auditor.getSQLs().size());
String actual = extract("WHERE", auditor.getSQLs().get(0));
if (dict instanceof DB2Dictionary)
return;
assertEquals(expected, actual);
}