mirror of https://github.com/apache/openjpa.git
OPENJPA-360 SQL FOR UPDATE OF incorrectly generated for DB2 UDB version8.1 or earlier and DB2 ISeries V5R3 or earlier.
These DB2 version also require the "optimize for <n> row" clause appear before FOR UPDATE clause. Due to this requirement, the OPTIMIZE clause will appear before FOR UPDATE clause for all DB2 versions. Also fixed the affected testcases. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@574464 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3d8748c427
commit
a4bf964c08
|
@ -50,12 +50,12 @@ public class DB2Dictionary
|
||||||
public String optimizeClause = "optimize for";
|
public String optimizeClause = "optimize for";
|
||||||
public String rowClause = "row";
|
public String rowClause = "row";
|
||||||
protected int db2ServerType = 0;
|
protected int db2ServerType = 0;
|
||||||
protected static final int db2ISeriesV5R3OrEarlier = 1;
|
public static final int db2ISeriesV5R3OrEarlier = 1;
|
||||||
protected static final int db2UDBV81OrEarlier = 2;
|
public static final int db2UDBV81OrEarlier = 2;
|
||||||
protected static final int db2ZOSV8xOrLater = 3;
|
public static final int db2ZOSV8xOrLater = 3;
|
||||||
protected static final int db2UDBV82OrLater = 4;
|
public static final int db2UDBV82OrLater = 4;
|
||||||
protected static final int db2ISeriesV5R4OrLater = 5;
|
public static final int db2ISeriesV5R4OrLater = 5;
|
||||||
private static final String forUpdateOfClause = "FOR UPDATE OF";
|
private static final String forUpdate = "FOR UPDATE";
|
||||||
private static final String withRSClause = "WITH RS";
|
private static final String withRSClause = "WITH RS";
|
||||||
private static final String withRRClause = "WITH RR";
|
private static final String withRRClause = "WITH RR";
|
||||||
private static final String useKeepUpdateLockClause
|
private static final String useKeepUpdateLockClause
|
||||||
|
@ -313,9 +313,12 @@ public class DB2Dictionary
|
||||||
* updateClause and isolationLevel hints
|
* updateClause and isolationLevel hints
|
||||||
*/
|
*/
|
||||||
protected String getForUpdateClause(JDBCFetchConfiguration fetch,
|
protected String getForUpdateClause(JDBCFetchConfiguration fetch,
|
||||||
boolean forUpdate) {
|
boolean isForUpdate) {
|
||||||
int isolationLevel;
|
int isolationLevel;
|
||||||
StringBuffer forUpdateString = new StringBuffer();
|
// For db2UDBV81OrEarlier and db2ISeriesV5R3OrEarlier:
|
||||||
|
// "optimize for" clause appears before "for update" clause.
|
||||||
|
StringBuffer forUpdateString = new StringBuffer(
|
||||||
|
getOptimizeClause(fetch));
|
||||||
try {
|
try {
|
||||||
// Determine the isolationLevel; the fetch
|
// Determine the isolationLevel; the fetch
|
||||||
// configuration data overrides the persistence.xml value
|
// configuration data overrides the persistence.xml value
|
||||||
|
@ -324,16 +327,15 @@ public class DB2Dictionary
|
||||||
else
|
else
|
||||||
isolationLevel = conf.getTransactionIsolationConstant();
|
isolationLevel = conf.getTransactionIsolationConstant();
|
||||||
|
|
||||||
if (forUpdate) {
|
if (isForUpdate) {
|
||||||
switch(db2ServerType) {
|
switch(db2ServerType) {
|
||||||
case db2ISeriesV5R3OrEarlier:
|
case db2ISeriesV5R3OrEarlier:
|
||||||
case db2UDBV81OrEarlier:
|
case db2UDBV81OrEarlier:
|
||||||
if (isolationLevel ==
|
if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE)
|
||||||
Connection.TRANSACTION_READ_UNCOMMITTED) {
|
forUpdateString.append(" ").append(forUpdateClause);
|
||||||
forUpdateString.append(" ").append(withRSClause)
|
else
|
||||||
.append(" ").append(forUpdateOfClause);
|
forUpdateString.append(" ").append(forUpdate)
|
||||||
} else
|
.append(" ").append(withRSClause);
|
||||||
forUpdateString.append(" ").append(forUpdateOfClause);
|
|
||||||
break;
|
break;
|
||||||
case db2ZOSV8xOrLater:
|
case db2ZOSV8xOrLater:
|
||||||
case db2UDBV82OrLater:
|
case db2UDBV82OrLater:
|
||||||
|
@ -368,7 +370,7 @@ public class DB2Dictionary
|
||||||
return forUpdateString.toString();
|
return forUpdateString.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDB2UDBV82OrLater() throws SQLException {
|
public boolean isDB2UDBV82OrLater() {
|
||||||
boolean match = false;
|
boolean match = false;
|
||||||
if ((databaseProductVersion.indexOf("SQL") != -1
|
if ((databaseProductVersion.indexOf("SQL") != -1
|
||||||
|| databaseProductName.indexOf("DB2/") != -1)
|
|| databaseProductName.indexOf("DB2/") != -1)
|
||||||
|
@ -377,8 +379,7 @@ public class DB2Dictionary
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDB2ZOSV8xOrLater()
|
public boolean isDB2ZOSV8xOrLater() {
|
||||||
throws SQLException {
|
|
||||||
boolean match = false;
|
boolean match = false;
|
||||||
if ((databaseProductVersion.indexOf("DSN") != -1
|
if ((databaseProductVersion.indexOf("DSN") != -1
|
||||||
|| databaseProductName.indexOf("DB2/") == -1)
|
|| databaseProductName.indexOf("DB2/") == -1)
|
||||||
|
@ -387,8 +388,7 @@ public class DB2Dictionary
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDB2ISeriesV5R3OrEarlier()
|
public boolean isDB2ISeriesV5R3OrEarlier() {
|
||||||
throws SQLException {
|
|
||||||
boolean match = false;
|
boolean match = false;
|
||||||
if (databaseProductName.indexOf("AS") != -1
|
if (databaseProductName.indexOf("AS") != -1
|
||||||
&& ((maj == 5 && min <=3) || maj < 5))
|
&& ((maj == 5 && min <=3) || maj < 5))
|
||||||
|
@ -396,8 +396,7 @@ public class DB2Dictionary
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDB2ISeriesV5R4OrLater()
|
public boolean isDB2ISeriesV5R4OrLater() {
|
||||||
throws SQLException {
|
|
||||||
boolean match = false;
|
boolean match = false;
|
||||||
if (databaseProductName.indexOf("AS") != -1
|
if (databaseProductName.indexOf("AS") != -1
|
||||||
&& (maj >=6 || (maj == 5 && min >=4)))
|
&& (maj >=6 || (maj == 5 && min >=4)))
|
||||||
|
@ -405,7 +404,7 @@ public class DB2Dictionary
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDB2UDBV81OrEarlier() throws SQLException {
|
public boolean isDB2UDBV81OrEarlier() {
|
||||||
boolean match = false;
|
boolean match = false;
|
||||||
if ((databaseProductVersion.indexOf("SQL") != -1
|
if ((databaseProductVersion.indexOf("SQL") != -1
|
||||||
|| databaseProductName.indexOf("DB2/") != -1) &&
|
|| databaseProductName.indexOf("DB2/") != -1) &&
|
||||||
|
@ -465,17 +464,16 @@ public class DB2Dictionary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SQLBuffer toSelect(Select sel, boolean forUpdate,
|
protected String getOptimizeClause(JDBCFetchConfiguration fetch) {
|
||||||
JDBCFetchConfiguration fetch) {
|
if (sel != null && sel.getExpectedResultCount() > 0) {
|
||||||
SQLBuffer buf = super.toSelect(sel, forUpdate, fetch);
|
StringBuffer buf = new StringBuffer();
|
||||||
|
|
||||||
if (sel.getExpectedResultCount() > 0) {
|
|
||||||
buf.append(" ").append(optimizeClause).append(" ")
|
buf.append(" ").append(optimizeClause).append(" ")
|
||||||
.append(String.valueOf(sel.getExpectedResultCount()))
|
.append(String.valueOf(sel.getExpectedResultCount()))
|
||||||
.append(" ").append(rowClause);
|
.append(" ").append(rowClause);
|
||||||
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenJPAException newStoreException(String msg, SQLException[] causes,
|
public OpenJPAException newStoreException(String msg, SQLException[] causes,
|
||||||
|
|
|
@ -325,6 +325,7 @@ public class DBDictionary
|
||||||
private Method _setBytes = null;
|
private Method _setBytes = null;
|
||||||
private Method _setString = null;
|
private Method _setString = null;
|
||||||
private Method _setCharStream = null;
|
private Method _setCharStream = null;
|
||||||
|
protected transient Select sel = null;
|
||||||
|
|
||||||
public DBDictionary() {
|
public DBDictionary() {
|
||||||
fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
|
fixedSizeTypeNameSet.addAll(Arrays.asList(new String[]{
|
||||||
|
@ -1988,6 +1989,7 @@ public class DBDictionary
|
||||||
*/
|
*/
|
||||||
public SQLBuffer toSelect(Select sel, boolean forUpdate,
|
public SQLBuffer toSelect(Select sel, boolean forUpdate,
|
||||||
JDBCFetchConfiguration fetch) {
|
JDBCFetchConfiguration fetch) {
|
||||||
|
this.sel = sel;
|
||||||
sel.addJoinClassConditions();
|
sel.addJoinClassConditions();
|
||||||
boolean update = forUpdate && sel.getFromSelect() == null;
|
boolean update = forUpdate && sel.getFromSelect() == null;
|
||||||
SQLBuffer select = getSelects(sel, false, update);
|
SQLBuffer select = getSelects(sel, false, update);
|
||||||
|
@ -2198,11 +2200,11 @@ public class DBDictionary
|
||||||
* updateClause and isolationLevel hints
|
* updateClause and isolationLevel hints
|
||||||
*/
|
*/
|
||||||
protected String getForUpdateClause(JDBCFetchConfiguration fetch,
|
protected String getForUpdateClause(JDBCFetchConfiguration fetch,
|
||||||
boolean forUpdate) {
|
boolean isForUpdate) {
|
||||||
if (fetch != null && fetch.getIsolation() != -1) {
|
if (fetch != null && fetch.getIsolation() != -1) {
|
||||||
throw new InvalidStateException(_loc.get(
|
throw new InvalidStateException(_loc.get(
|
||||||
"isolation-level-config-not-supported", getClass().getName()));
|
"isolation-level-config-not-supported", getClass().getName()));
|
||||||
} else if (forUpdate && !simulateLocking) {
|
} else if (isForUpdate && !simulateLocking) {
|
||||||
assertSupport(supportsSelectForUpdate, "SupportsSelectForUpdate");
|
assertSupport(supportsSelectForUpdate, "SupportsSelectForUpdate");
|
||||||
return forUpdateClause;
|
return forUpdateClause;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -81,37 +81,23 @@ public class TestIsolationLevelOverride
|
||||||
|
|
||||||
q.getResultList();
|
q.getResultList();
|
||||||
if (dict instanceof DB2Dictionary) {
|
if (dict instanceof DB2Dictionary) {
|
||||||
if ((((DB2Dictionary) dict).getDb2ServerType() == 1)
|
int db2server = ((DB2Dictionary) dict).getDb2ServerType();
|
||||||
|| (((DB2Dictionary) dict).getDb2ServerType()== 2)) {
|
if (db2server == DB2Dictionary.db2ISeriesV5R3OrEarlier
|
||||||
|
|| db2server == DB2Dictionary.db2UDBV81OrEarlier) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.id, t0.booleanField, t0.byteField,"
|
assertContainsSQL(" FOR UPDATE");
|
||||||
+ " t0.charField, t0.dateField, t0.doubleField,"
|
|
||||||
+ " t0.floatField, t0.intField, t0.longField, "
|
|
||||||
+ "t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE \\(t0.intField = \\?\\) "
|
|
||||||
+ " FOR UPDATE OF");
|
|
||||||
}
|
}
|
||||||
// it is DB2 v82 or later
|
// it is DB2 v82 or later
|
||||||
else if ((((DB2Dictionary) dict).getDb2ServerType() == 3)
|
else if (db2server == DB2Dictionary.db2ZOSV8xOrLater
|
||||||
|| (((DB2Dictionary) dict).getDb2ServerType() == 4)) {
|
|| db2server == DB2Dictionary.db2UDBV82OrLater) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.id, t0.booleanField, t0.byteField,"
|
assertContainsSQL(" FOR READ ONLY WITH RR USE AND KEEP "
|
||||||
+ " t0.charField, t0.dateField, t0.doubleField,"
|
|
||||||
+ " t0.floatField, t0.intField, t0.longField, "
|
|
||||||
+ "t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE \\(t0.intField = \\?\\) "
|
|
||||||
+ " FOR READ ONLY WITH RR USE AND KEEP "
|
|
||||||
+ "UPDATE LOCKS");
|
+ "UPDATE LOCKS");
|
||||||
}
|
}
|
||||||
else if (((DB2Dictionary) dict).getDb2ServerType() == 5) {
|
else if (db2server == DB2Dictionary.db2ISeriesV5R4OrLater) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.id, t0.booleanField, t0.byteField,"
|
assertContainsSQL(" FOR READ ONLY WITH RR USE AND KEEP"
|
||||||
+ " t0.charField, t0.dateField, t0.doubleField,"
|
+ " EXCLUSIVE LOCKS");
|
||||||
+ " t0.floatField, t0.intField, t0.longField, "
|
|
||||||
+ "t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE \\(t0.intField = \\?\\) "
|
|
||||||
+ " FOR READ ONLY WITH RR USE AND KEEP EXCLUSIVE "
|
|
||||||
+ "LOCKS");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fail("OpenJPA currently only supports "
|
fail("OpenJPA currently only supports "
|
||||||
|
@ -124,37 +110,25 @@ public class TestIsolationLevelOverride
|
||||||
.setIsolation(IsolationLevel.SERIALIZABLE);
|
.setIsolation(IsolationLevel.SERIALIZABLE);
|
||||||
em.find(AllFieldTypes.class, 0);
|
em.find(AllFieldTypes.class, 0);
|
||||||
if (dict instanceof DB2Dictionary ) {
|
if (dict instanceof DB2Dictionary ) {
|
||||||
if ((((DB2Dictionary) dict).getDb2ServerType() == 1)
|
int db2server = ((DB2Dictionary) dict).getDb2ServerType();
|
||||||
|| (((DB2Dictionary) dict).getDb2ServerType()== 2)) {
|
if (db2server == DB2Dictionary.db2ISeriesV5R3OrEarlier
|
||||||
|
|| db2server == DB2Dictionary.db2UDBV81OrEarlier) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.booleanField, t0.byteField, "
|
assertContainsSQL(" optimize for 1 row FOR UPDATE");
|
||||||
+ "t0.charField, t0.dateField, t0.doubleField,"
|
|
||||||
+ " t0.floatField, t0.intField, t0.longField,"
|
|
||||||
+ " t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE t0.id = \\? "
|
|
||||||
+ " FOR UPDATE OF optimize for 1 row");
|
|
||||||
}
|
}
|
||||||
// it is DB2 v82 or later
|
// it is DB2 v82 or later
|
||||||
else if ((((DB2Dictionary) dict).getDb2ServerType() == 3)
|
else if (db2server == DB2Dictionary.db2ZOSV8xOrLater
|
||||||
|| (((DB2Dictionary) dict).getDb2ServerType() == 4)) {
|
|| db2server == DB2Dictionary.db2UDBV82OrLater) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.booleanField, t0.byteField, "
|
assertContainsSQL(" optimize for 1 row"
|
||||||
+ "t0.charField, t0.dateField, t0.doubleField,"
|
|
||||||
+ " t0.floatField, t0.intField, t0.longField,"
|
|
||||||
+ " t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE t0.id = \\? "
|
|
||||||
+ " FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS"
|
+ " FOR READ ONLY WITH RR USE AND KEEP UPDATE LOCKS"
|
||||||
+ " optimize for 1 row");
|
);
|
||||||
}
|
}
|
||||||
else if (((DB2Dictionary) dict).getDb2ServerType() == 5) {
|
else if (db2server == DB2Dictionary.db2ISeriesV5R4OrLater) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.booleanField, t0.byteField, "
|
assertContainsSQL(" optimize for 1 row"
|
||||||
+ "t0.charField, t0.dateField, t0.doubleField,"
|
|
||||||
+ " t0.floatField, t0.intField, t0.longField,"
|
|
||||||
+ " t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE t0.id = \\? "
|
|
||||||
+ " FOR READ ONLY WITH RR USE AND KEEP EXCLUSIVE"
|
+ " FOR READ ONLY WITH RR USE AND KEEP EXCLUSIVE"
|
||||||
+ " LOCKS optimize for 1 row");
|
+ " LOCKS");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fail("OpenJPA currently only supports per-query"
|
fail("OpenJPA currently only supports per-query"
|
||||||
|
|
|
@ -81,22 +81,14 @@ public class TestOptimizeForClause
|
||||||
}
|
}
|
||||||
if (dict instanceof DB2Dictionary) {
|
if (dict instanceof DB2Dictionary) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.id, t0.booleanField, t0.byteField," +
|
assertContainsSQL(" optimize for 8 row");
|
||||||
" t0.charField, t0.dateField, t0.doubleField, " +
|
|
||||||
"t0.floatField, t0.intField, t0.longField, " +
|
|
||||||
"t0.shortField, t0.stringField FROM AllFieldTypes " +
|
|
||||||
"t0 WHERE \\(t0.intField = \\?\\) optimize for 8 row");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
em.find(AllFieldTypes.class, 0);
|
em.find(AllFieldTypes.class, 0);
|
||||||
if (dict instanceof DB2Dictionary ) {
|
if (dict instanceof DB2Dictionary ) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.booleanField, t0.byteField, " +
|
assertContainsSQL(" optimize for 1 row");
|
||||||
"t0.charField, t0.dateField, t0.doubleField, " +
|
|
||||||
"t0.floatField, t0.intField, t0.longField, " +
|
|
||||||
"t0.shortField, t0.stringField FROM AllFieldTypes" +
|
|
||||||
" t0 WHERE t0.id = \\? optimize for 1 row");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,14 @@ public class TestSelectForUpdateOverride
|
||||||
extends SQLListenerTestCase {
|
extends SQLListenerTestCase {
|
||||||
|
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
setUp(AllFieldTypes.class,
|
setUp(
|
||||||
|
// "openjpa.ConnectionDriverName",
|
||||||
|
// "org.apache.commons.dbcp.BasicDataSource",
|
||||||
|
|
||||||
|
"openjpa.ConnectionProperties",
|
||||||
|
"DriverClassName=com.ibm.db2.jcc.DB2Driver,Url=jdbc:db2:demodb"
|
||||||
|
,"openjpa.jdbc.SynchronizeMappings",
|
||||||
|
AllFieldTypes.class,
|
||||||
"openjpa.Optimistic", "false",
|
"openjpa.Optimistic", "false",
|
||||||
"openjpa.LockManager", "pessimistic",
|
"openjpa.LockManager", "pessimistic",
|
||||||
"openjpa.ReadLockLevel", "none");
|
"openjpa.ReadLockLevel", "none");
|
||||||
|
@ -57,37 +64,24 @@ public class TestSelectForUpdateOverride
|
||||||
em.find(AllFieldTypes.class, 0);
|
em.find(AllFieldTypes.class, 0);
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
if (dict instanceof DB2Dictionary) {
|
if (dict instanceof DB2Dictionary) {
|
||||||
if ((((DB2Dictionary) dict).getDb2ServerType() == 1)
|
int db2server = ((DB2Dictionary) dict).getDb2ServerType();
|
||||||
|| (((DB2Dictionary) dict).getDb2ServerType()== 2)) {
|
if (db2server == DB2Dictionary.db2ISeriesV5R3OrEarlier
|
||||||
|
|| db2server == DB2Dictionary.db2UDBV81OrEarlier) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.booleanField, t0.byteField, "
|
assertContainsSQL(" optimize for 1 row FOR UPDATE");
|
||||||
+ "t0.charField, t0.dateField, t0.doubleField,"
|
|
||||||
+ " t0.floatField, t0.intField, t0.longField,"
|
|
||||||
+ " t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE t0.id = \\? "
|
|
||||||
+ " FOR UPDATE OF optimize for 1 row");
|
|
||||||
}
|
}
|
||||||
// it is DB2 v82 or later
|
// it is DB2 v82 or later
|
||||||
else if ((((DB2Dictionary) dict).getDb2ServerType() == 3)
|
else if (db2server == DB2Dictionary.db2ZOSV8xOrLater
|
||||||
|| (((DB2Dictionary) dict).getDb2ServerType() == 4)) {
|
|| db2server == DB2Dictionary.db2UDBV82OrLater) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.booleanField, t0.byteField, "
|
assertContainsSQL(" optimize for 1 row"
|
||||||
+ "t0.charField, t0.dateField, t0.doubleField,"
|
+ " FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS");
|
||||||
+ " t0.floatField, t0.intField, t0.longField,"
|
|
||||||
+ " t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE t0.id = \\? "
|
|
||||||
+ " FOR READ ONLY WITH RS USE AND KEEP UPDATE LOCKS"
|
|
||||||
+ " optimize for 1 row");
|
|
||||||
}
|
}
|
||||||
else if (((DB2Dictionary) dict).getDb2ServerType() == 5) {
|
else if (db2server == DB2Dictionary.db2ISeriesV5R4OrLater) {
|
||||||
assertEquals(1, sql.size());
|
assertEquals(1, sql.size());
|
||||||
assertSQL("SELECT t0.booleanField, t0.byteField, "
|
assertContainsSQL(" optimize for 1 row"
|
||||||
+ "t0.charField, t0.dateField, t0.doubleField,"
|
|
||||||
+ " t0.floatField, t0.intField, t0.longField,"
|
|
||||||
+ " t0.shortField, t0.stringField FROM "
|
|
||||||
+ "AllFieldTypes t0 WHERE t0.id = \\? "
|
|
||||||
+ " FOR READ ONLY WITH RS USE AND KEEP EXCLUSIVE LOCKS"
|
+ " FOR READ ONLY WITH RS USE AND KEEP EXCLUSIVE LOCKS"
|
||||||
+ " optimize for 1 row");
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fail("OpenJPA currently only supports per-query isolation "
|
fail("OpenJPA currently only supports per-query isolation "
|
||||||
|
|
|
@ -78,6 +78,21 @@ public abstract class SQLListenerTestCase
|
||||||
+ " should not have been executed in SQL statements: " + sql);
|
+ " should not have been executed in SQL statements: " + sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm that the executed SQL String contains the specified sqlExp.
|
||||||
|
*
|
||||||
|
* @param sqlExp the SQL expression. E.g., "SELECT BADCOLUMN .*"
|
||||||
|
*/
|
||||||
|
public void assertContainsSQL(String sqlExp) {
|
||||||
|
for (String statement : sql) {
|
||||||
|
if (statement.contains(sqlExp))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail("Expected regular expression <" + sqlExp + "> to be"
|
||||||
|
+ " contained in SQL statements: " + sql);
|
||||||
|
}
|
||||||
|
|
||||||
public class Listener
|
public class Listener
|
||||||
extends AbstractJDBCListener {
|
extends AbstractJDBCListener {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue