mirror of https://github.com/apache/openjpa.git
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:
parent
d86b15e30d
commit
09859699f9
|
@ -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,7 +1727,7 @@ 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);
|
||||||
|
@ -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 <name> UNIQUE (<col list>)</code>
|
* Returns <code>CONSTRAINT <name> UNIQUE (<col list>)</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;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue