问题
It seems NOWAIT is not supported by HSQLDB in Oracle syntax.
HSQLDB version: 2.3.3
with
SET DATABASE SQL SYNTAX ORA TRUE;
Exception produced on the SQL
select a, b, c from sometable where id=1 for update NOWAIT
The exception
Caused by: org.hsqldb.HsqlException: unexpected token: NOWAIT
at org.hsqldb.error.Error.parseError(Unknown Source)
at org.hsqldb.ParserBase.unexpectedToken(Unknown Source)
at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
at org.hsqldb.Session.compileStatement(Unknown Source)
at org.hsqldb.StatementManager.compile(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
- Does anyone know if HSQLDB does not supports this ?
- Any ideas how to avoid this exception without modifying the original SQL. I can ignore the NOWAIT functionality in my unit tests but just cant modify the SQL. Additional info: we use spring-jbdc and JdbcTemplate and thinking about intercepting this to replace sqls with NOWAIT as an hack in the JUnit test setup.
回答1:
Found answer to my own question finally after digging hsqldb source code on sourceforge.
Version 2.3.3 of HSQLDB does NOT support NOWAIT.
I have asked this question in their Discussion Forum and raised the issue however its not like GitHub where you can create an issue so no formal Issue/Request opened.
I am getting along with a bad hack for now modifying HSQLDB
code myself org.hsqldb.ParserDQL
class to just ignore the NOWAIT in the select-for-update SQL.
If anyone has better answer I will accept their answer.
UPDATE: (Aug-24-2015)
Received confirmation from HSQLDB forum that NOWAIT will be ignored. Meanwhile I am posting the code snippet to ignore NOWAIT that I received from the HSQLDB sourceforge forum. You may want to wait for the next version of HSQLDB than adding this to your code base (as a hack).
if (Tokens.T_NOWAIT.equals(token.tokenString)) {
read();
}
UPDATED to show the full context as to where to add the above snippet in the ParserDQL.java
/**
* Retrieves a SELECT or other query expression Statement from this parse context.
*/
StatementQuery compileCursorSpecification(RangeGroup[] rangeGroups,
int props, boolean isRoutine) {
OrderedHashSet colNames = null;
QueryExpression queryExpression = XreadQueryExpression();
if (token.tokenType == Tokens.FOR) {
read();
if (token.tokenType == Tokens.READ
|| token.tokenType == Tokens.FETCH) {
read();
readThis(Tokens.ONLY);
props = ResultProperties.addUpdatable(props, false);
} else {
readThis(Tokens.UPDATE);
props = ResultProperties.addUpdatable(props, true);
if (token.tokenType == Tokens.OF) {
readThis(Tokens.OF);
colNames = new OrderedHashSet();
readColumnNameList(colNames, null, false);
}
if (Tokens.T_NOWAIT.equalsIgnoreCase(token.tokenString)) {
readIfThis(Tokens.X_IDENTIFIER);
}
}
}
来源:https://stackoverflow.com/questions/32126332/hsqldb-oracle-mode-select-for-update-nowait