blob: 4b151e4463d566e4474a9d7219055ae8a5d971c6 [file] [log] [blame]
/*
* 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;
}
}
}