OpenJPA-1002: fixed select range for Oracle drivers, patch submitted by Amy Yang and Ravi Palacherla

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@769505 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
David Ezzio 2009-04-28 19:14:40 +00:00
parent d86b15e30d
commit 09859699f9
4 changed files with 138 additions and 34 deletions

View File

@ -370,7 +370,7 @@ public class DBDictionary
public int batchLimit = NO_BATCH; public int batchLimit = NO_BATCH;
public final Map<Integer,Set<String>> sqlStateCodes = public final Map<Integer,Set<String>> sqlStateCodes =
new HashMap<Integer, Set<String>>(); new HashMap<Integer, Set<String>>();
public DBDictionary() { public DBDictionary() {
fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{ fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
@ -1727,14 +1727,14 @@ public class DBDictionary
* size clause will be inserted appropriately. * size clause will be inserted appropriately.
*/ */
protected String insertSize(String typeName, String size) { protected String insertSize(String typeName, String size) {
if (StringUtils.isEmpty(size)) { if (StringUtils.isEmpty(size)) {
int idx = typeName.indexOf("{0}"); int idx = typeName.indexOf("{0}");
if (idx != -1) { if (idx != -1) {
return typeName.substring(0, idx); return typeName.substring(0, idx);
} }
return typeName; return typeName;
} }
int idx = typeName.indexOf("{0}"); int idx = typeName.indexOf("{0}");
if (idx != -1) { if (idx != -1) {
// replace '{0}' with size // replace '{0}' with size
@ -1883,7 +1883,7 @@ public class DBDictionary
from.append("("); from.append("(");
from.append(toSelect(subSelect, null, subFrom, where, from.append(toSelect(subSelect, null, subFrom, where,
sel.getGrouping(), sel.getHaving(), null, sel.isDistinct(), sel.getGrouping(), sel.getHaving(), null, sel.isDistinct(),
false, sel.getStartIndex(), sel.getEndIndex(), true)); false, sel.getStartIndex(), sel.getEndIndex(), true, sel));
from.append(")"); from.append(")");
if (requiresAliasForSubselect) if (requiresAliasForSubselect)
from.append(" ").append(Select.FROM_SELECT_ALIAS); from.append(" ").append(Select.FROM_SELECT_ALIAS);
@ -2076,7 +2076,7 @@ public class DBDictionary
Val val = (Val) next.getValue(); Val val = (Val) next.getValue();
if (val == null) if (val == null)
val = new Null(); val = new Null();
Column col = fmd.getColumns()[0]; Column col = fmd.getColumns()[0];
if (allowAlias) { if (allowAlias) {
sql.append(sel.getColumnAlias(col)); sql.append(sel.getColumnAlias(col));
@ -2371,11 +2371,12 @@ public class DBDictionary
/** /**
* Combine the given components into a SELECT statement. * Combine the given components into a SELECT statement.
*/ */
public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch, protected SQLBuffer toSelect(SQLBuffer selects,
JDBCFetchConfiguration fetch,
SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer from, SQLBuffer where, SQLBuffer group,
SQLBuffer having, SQLBuffer order, SQLBuffer having, SQLBuffer order,
boolean distinct, boolean forUpdate, long start, long end, boolean distinct, boolean forUpdate, long start, long end,
boolean subselect) { boolean subselect, Select sel) {
return toOperation(getSelectOperation(fetch), selects, from, where, return toOperation(getSelectOperation(fetch), selects, from, where,
group, having, order, distinct, start, end, group, having, order, distinct, start, end,
getForUpdateClause(fetch, forUpdate, null), subselect); getForUpdateClause(fetch, forUpdate, null), subselect);
@ -2395,7 +2396,8 @@ public class DBDictionary
/** /**
* Combine the given components into a SELECT statement. * Combine the given components into a SELECT statement.
*/ */
public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch, protected SQLBuffer toSelect(SQLBuffer selects,
JDBCFetchConfiguration fetch,
SQLBuffer from, SQLBuffer where, SQLBuffer group, SQLBuffer from, SQLBuffer where, SQLBuffer group,
SQLBuffer having, SQLBuffer order, SQLBuffer having, SQLBuffer order,
boolean distinct, boolean forUpdate, long start, long end, boolean distinct, boolean forUpdate, long start, long end,
@ -3103,7 +3105,7 @@ public class DBDictionary
public String[] getCreateTableSQL(Table table) { public String[] getCreateTableSQL(Table table) {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
String tableName = checkNameLength(getFullName(table, false), String tableName = checkNameLength(getFullName(table, false),
maxTableNameLength, "long-table-name"); maxTableNameLength, "long-table-name");
buf.append("CREATE TABLE ").append(tableName); buf.append("CREATE TABLE ").append(tableName);
if (supportsComments && table.hasComment()) { if (supportsComments && table.hasComment()) {
buf.append(" "); buf.append(" ");
@ -3178,7 +3180,7 @@ public class DBDictionary
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
buf.append("CREATE SEQUENCE "); buf.append("CREATE SEQUENCE ");
String seqName = checkNameLength(getFullName(seq), maxTableNameLength, String seqName = checkNameLength(getFullName(seq), maxTableNameLength,
"long-seq-name"); "long-seq-name");
buf.append(seqName); buf.append(seqName);
if (seq.getInitialValue() != 0) if (seq.getInitialValue() != 0)
buf.append(" START WITH ").append(seq.getInitialValue()); buf.append(" START WITH ").append(seq.getInitialValue());
@ -3318,7 +3320,7 @@ public class DBDictionary
protected String getDeclareColumnSQL(Column col, boolean alter) { protected String getDeclareColumnSQL(Column col, boolean alter) {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
String columnName = checkNameLength(col.getName(), maxColumnNameLength, String columnName = checkNameLength(col.getName(), maxColumnNameLength,
"long-column-name"); "long-column-name");
buf.append(columnName).append(" "); buf.append(columnName).append(" ");
buf.append(getTypeName(col)); buf.append(getTypeName(col));
@ -3499,7 +3501,7 @@ public class DBDictionary
/** /**
* Return the declaration SQL for the given unique constraint. This * Return the declaration SQL for the given unique constraint. This
* method is used from within {@link #getCreateTableSQL}. * method is used from within {@link #getCreateTableSQL}.
* Returns <code>CONSTRAINT &lt;name&gt; UNIQUE (&lt;col list&gt;)</code> * Returns <code>CONSTRAINT &lt;name&gt; UNIQUE (&lt;col list&gt;)</code>
* by default. * by default.
*/ */
protected String getUniqueConstraintSQL(Unique unq) { protected String getUniqueConstraintSQL(Unique unq) {
@ -3510,7 +3512,7 @@ public class DBDictionary
if (unq.getName() != null if (unq.getName() != null
&& CONS_NAME_BEFORE.equals(constraintNameMode)) && CONS_NAME_BEFORE.equals(constraintNameMode))
buf.append("CONSTRAINT ").append(checkNameLength(unq.getName(), buf.append("CONSTRAINT ").append(checkNameLength(unq.getName(),
maxConstraintNameLength, "long-constraint-name")).append(" "); maxConstraintNameLength, "long-constraint-name")).append(" ");
buf.append("UNIQUE "); buf.append("UNIQUE ");
if (unq.getName() != null && CONS_NAME_MID.equals(constraintNameMode)) if (unq.getName() != null && CONS_NAME_MID.equals(constraintNameMode))
buf.append(unq.getName()).append(" "); buf.append(unq.getName()).append(" ");
@ -4163,22 +4165,22 @@ public class DBDictionary
if (stream == null) { // User supplied dictionary but no error codes xml if (stream == null) { // User supplied dictionary but no error codes xml
// use default // use default
stream = DBDictionary.class.getResourceAsStream(rsrc); stream = DBDictionary.class.getResourceAsStream(rsrc);
dictionaryClassName = getClass().getSuperclass().getName(); dictionaryClassName = getClass().getSuperclass().getName();
} }
codeReader.parse(stream, dictionaryClassName, this); codeReader.parse(stream, dictionaryClassName, this);
} }
public void addErrorCode(int errorType, String errorCode) { public void addErrorCode(int errorType, String errorCode) {
if (errorCode == null || errorCode.trim().length() == 0) if (errorCode == null || errorCode.trim().length() == 0)
return; return;
Set<String> codes = sqlStateCodes.get(errorType); Set<String> codes = sqlStateCodes.get(errorType);
if (codes == null) { if (codes == null) {
codes = new HashSet<String>(); codes = new HashSet<String>();
codes.add(errorCode.trim()); codes.add(errorCode.trim());
sqlStateCodes.put(errorType, codes); sqlStateCodes.put(errorType, codes);
} else { } else {
codes.add(errorCode.trim()); codes.add(errorCode.trim());
} }
} }
/** /**
@ -4331,11 +4333,11 @@ public class DBDictionary
*/ */
public OpenJPAException newStoreException(String msg, SQLException[] causes, public OpenJPAException newStoreException(String msg, SQLException[] causes,
Object failed) { Object failed) {
if (causes != null && causes.length > 0) { if (causes != null && causes.length > 0) {
OpenJPAException ret = narrow(msg, causes[0]); OpenJPAException ret = narrow(msg, causes[0]);
ret.setFailedObject(failed).setNestedThrowables(causes); ret.setFailedObject(failed).setNestedThrowables(causes);
return ret; return ret;
} }
return new StoreException(msg).setFailedObject(failed). return new StoreException(msg).setFailedObject(failed).
setNestedThrowables(causes); setNestedThrowables(causes);
} }
@ -4718,9 +4720,9 @@ public class DBDictionary
* given message key otherwise returns the same name. * given message key otherwise returns the same name.
*/ */
final String checkNameLength(String name, int length, String msgKey) { final String checkNameLength(String name, int length, String msgKey) {
if (name.length() > length) if (name.length() > length)
throw new UserException(_loc.get(msgKey, name, name.length(), throw new UserException(_loc.get(msgKey, name, name.length(),
length)); length));
return name; return name;
} }
} }

View File

@ -360,7 +360,16 @@ public class OracleDictionary
return buf; return buf;
} }
public SQLBuffer toSelect(SQLBuffer select, JDBCFetchConfiguration fetch, protected SQLBuffer toSelect(SQLBuffer select, JDBCFetchConfiguration fetch,
SQLBuffer tables, SQLBuffer where, SQLBuffer group,
SQLBuffer having, SQLBuffer order,
boolean distinct, boolean forUpdate, long start, long end,
boolean subselect, Select sel) {
return toSelect(select, fetch, tables, where, group, having, order,
distinct, forUpdate, start, end, sel);
}
protected SQLBuffer toSelect(SQLBuffer select, JDBCFetchConfiguration fetch,
SQLBuffer tables, SQLBuffer where, SQLBuffer group, SQLBuffer tables, SQLBuffer where, SQLBuffer group,
SQLBuffer having, SQLBuffer order, SQLBuffer having, SQLBuffer order,
boolean distinct, boolean forUpdate, long start, long end, boolean distinct, boolean forUpdate, long start, long end,

View File

@ -0,0 +1,92 @@
/*
* 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.jdbc.meta;
import java.util.*;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.kernel.jpql.JPQLParser;
import org.apache.openjpa.persistence.FetchPlan;
import org.apache.openjpa.persistence.OpenJPAQuery;
import org.apache.openjpa.persistence.jdbc.common.apps.*;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.jdbc.common.apps.EagerOuterJoinPC;
public class TestRangeQuery extends
org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest {
/** Creates a new instance of TestRangeQuery */
public TestRangeQuery(String name) {
super(name);
}
public boolean skipTest() {
DBDictionary dict = ((JDBCConfiguration) getConfiguration()).
getDBDictionaryInstance();
return !dict.supportsSubselect;
}
public void setUp() {
deleteAll(HelperPC.class);
deleteAll(EagerOuterJoinPC2.class);
deleteAll(EagerOuterJoinPC.class);
}
public void testQueryRange() {
insertManyStringList();
OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
FetchPlan fetch = (FetchPlan) em.getFetchPlan();
fetch.addField(EagerOuterJoinPC.class, "stringList");
fetch.setFetchBatchSize(3);
OpenJPAQuery q = em.createQuery(JPQLParser.LANG_JPQL,
"select x from EagerOuterJoinPC x order by x.name asc");
q.setFirstResult(5).setMaxResults(15);
List results = (List) q.getResultList();
assertEquals(5, results.size());
for (int i = 0; i < results.size(); i++) {
EagerOuterJoinPC pc = (EagerOuterJoinPC) results.get(i);
assertEquals(String.valueOf(i + 5), pc.getName());
}
q.closeAll();
em.close();
}
@SuppressWarnings("unchecked")
private void insertManyStringList() {
OpenJPAEntityManager em =(OpenJPAEntityManager)currentEntityManager();
startTx(em);;
for (int i = 0; i < 10; i++) {
EagerOuterJoinPC pc = new EagerOuterJoinPC();
pc.setName(String.valueOf(i));
pc.getStringList().add(i + ".1");
pc.getStringList().add(i + ".2");
em.persist(pc);
}
endTx(em);;
em.close();
}
}

View File

@ -39,5 +39,6 @@
<class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC4</class> <class>org.apache.openjpa.persistence.jdbc.common.apps.HelperPC4</class>
<class>org.apache.openjpa.persistence.jdbc.common.apps.InvertA</class> <class>org.apache.openjpa.persistence.jdbc.common.apps.InvertA</class>
<class>org.apache.openjpa.persistence.jdbc.common.apps.InvertB</class> <class>org.apache.openjpa.persistence.jdbc.common.apps.InvertB</class>
<class>org.apache.openjpa.persistence.jdbc.common.apps.EagerOuterJoinPC</class>
</persistence-unit> </persistence-unit>
</persistence> </persistence>