/* | |
* TestQuotedNumbersInFilters.java | |
* | |
* Created on October 18, 2006, 2:29 PM | |
* | |
* To change this template, choose Tools | Template Manager | |
* and open the template in the editor. | |
*/ | |
/* | |
* 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.query; | |
import java.util.Collection; | |
import java.util.HashMap; | |
import java.util.Map; | |
import javax.persistence.Query; | |
import org.apache.openjpa.persistence.query.common.apps.RuntimeTest1; | |
import org.apache.openjpa.persistence.OpenJPAEntityManager; | |
import org.apache.openjpa.persistence.OpenJPAQuery; | |
public class TestQuotedNumbersInFilters2 extends BaseQueryTest { | |
public TestQuotedNumbersInFilters2(String name) { | |
super(name); | |
} | |
public void setUp() { | |
deleteAll(RuntimeTest1.class); | |
OpenJPAEntityManager pm = getEM(); | |
startTx(pm); | |
pm.persist(new RuntimeTest1("foo", 3)); | |
pm.persist(new RuntimeTest1("bar", 15)); | |
pm.persist(new RuntimeTest1("baz", -8)); | |
pm.persist(new RuntimeTest1("baz2", 45)); // 45 is '-' | |
pm.persist(new RuntimeTest1("3", (int) '4')); | |
endTx(pm); | |
endEm(pm); | |
// make sure everything is working as expected for the base case. | |
assertEquals(1, helper("intField = -8")); | |
assertEquals(1, helper("intField = 15")); | |
assertEquals(1, helper("intField = 3")); | |
assertEquals(0, helper("intField = 51")); // the int value of '3' | |
assertEquals(0, helper("intField = 4")); | |
assertEquals(1, helper("intField = 52")); // the int value of '4' | |
assertEquals(1, helper("stringField = \'foo\'")); | |
assertEquals(1, helper("stringField = \'bar\'")); | |
} | |
public void testUnquotedNumbersWithExtraPrecision() { | |
assertEquals(1, helper("intField = 15")); | |
assertEquals(1, helper("intField = -8")); | |
assertEquals(1, helper("intField = 3")); | |
assertEquals(1, helper("intField = 45")); | |
// try { | |
// // test without casting ... some DBs don't like this | |
//// assertEquals(1, helper("intField = 15.0")); | |
//// assertEquals(1, helper("intField = -8.0")); | |
// assertEquals(1, helper("intField = 3.0")); | |
// assertEquals(1, helper("intField = 45.0")); | |
// } catch (Exception jdoe) { | |
// bug(AbstractTestCase.Platform.HYPERSONIC, 414, jdoe, | |
// "Some databases require explicit casts"); | |
// } | |
} | |
public void testSingleQuotedStrings() { | |
assertEquals(1, helper("stringField = 'foo'")); | |
assertEquals(1, helper("stringField = '3'")); | |
} | |
public void testDoubleQuotedStrings() { | |
assertEquals(1, helper("stringField = \'foo\'")); | |
assertEquals(1, helper("stringField = \'3\'")); | |
} | |
/** | |
* Kodo 3.1 and prior treated single-quoted numbers as character literals, | |
* to the degree that prepared statement setInt() calls were made. | |
* Only the first digit of multiple-digit single-quoted numbers was used. | |
* FIX ME: aokeke - commenting this --> applies to kodo 3.1 and prior | |
*/ | |
public void testKodo31SingleQuotedMultipleCharacterBehavior() { | |
assertEquals(0, helper31("intField = '15'", true)); // looks like '1' | |
assertEquals(0, helper31("intField = '52'", true)); // looks like '5' | |
assertEquals(1, helper31("intField = '49'", true)); // looks like '4' | |
assertEquals(1, helper31("intField = '-8'", true)); // looks like '-' | |
assertEquals(0, helper31("intField = '15'", false)); | |
assertEquals(0, helper31("intField = '52'", false)); | |
} | |
/** | |
* Kodo 3.1 and prior did not match negative numbers of different types | |
* in in-mem queries. | |
*/ | |
public void testKodo31UnquotedInMemBehavior() { | |
assertEquals(1, helper31("intField = 3", false)); | |
assertEquals(1, helper31("intField = -8", false)); | |
assertEquals(1, helper31("intField = 15", false)); | |
assertEquals(1, helper31("intField = 45", false)); | |
} | |
public void testKodo31UnquotedDatastoreBehavior() { | |
assertEquals(1, helper31("intField = 3", false)); | |
assertEquals(1, helper31("intField = -8", false)); | |
assertEquals(1, helper31("intField = 15", false)); | |
assertEquals(1, helper31("intField = 45", false)); | |
} | |
/** | |
* Returns the # of matches to the query. | |
*/ | |
private long helper(String filter) { | |
return helper(filter, false); | |
} | |
/** | |
* Returns the # of matches to the query. Returns -1 if shouldFail | |
* is true and the query raised an exception in both in-mem and datastore | |
* queries. | |
*/ | |
private long helper(String filter, boolean shouldFail) { | |
OpenJPAEntityManager pm = getEM(); | |
OpenJPAQuery q = | |
pm.createQuery("SELECT r FROM RuntimeTest1 r WHERE r." + filter); | |
long datastore = getResults(q, shouldFail); | |
q.setCandidateCollection((Collection) q.getResultList()); | |
long inmem = getResults(q, shouldFail); | |
if (datastore != inmem) | |
fail("datastore query returned " + datastore + " values; " + | |
"inmem query returned " + inmem); | |
endEm(pm); | |
return datastore; | |
} | |
/** | |
* Returns the # of matches to the query. Performs the query in datastore | |
* or memory as appropriate. | |
*/ | |
private long helper31(String filter, boolean datastore) { | |
Map props = new HashMap(); | |
props.put("openjpa.Compatibility", "QuotedNumbersInQueries=true"); | |
OpenJPAEntityManager pm = getEmf(props).createEntityManager(); | |
try { | |
OpenJPAQuery q = pm.createQuery( | |
"SELECT r FROM RuntimeTest1 r WHERE r." + filter); | |
if (!datastore) | |
q.setCandidateCollection((Collection) q.getResultList()); | |
return getResults(q, false); | |
} | |
finally { | |
endEm(pm); | |
} | |
} | |
private long getResults(Query q, boolean shouldFail) { | |
try { | |
Integer result = new Integer(q.getResultList().size()); | |
if (shouldFail) { | |
fail("should have failed"); | |
} | |
return ((Number) result).longValue(); | |
} catch (IllegalArgumentException e) { | |
if (!shouldFail) | |
throw e; | |
return -1; | |
} | |
} | |
} |