Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public class PlainSelect implements SelectBody {
private boolean forUpdate = false;
private Table forUpdateTable = null;
private boolean useBrackets = false;

private Wait wait;

public boolean isUseBrackets() {
return useBrackets;
}
Expand Down Expand Up @@ -266,6 +267,25 @@ public OracleHint getOracleHint() {
public void setOracleHint(OracleHint oracleHint) {
this.oracleHint = oracleHint;
}

/**
* Sets the {@link Wait} for this SELECT
*
* @param wait
* the {@link Wait} for this SELECT
*/
public void setWait(final Wait wait) {
this.wait = wait;
}

/**
* Returns the value of the {@link Wait} set for this SELECT
*
* @return the value of the {@link Wait} set for this SELECT
*/
public Wait getWait() {
return wait;
}

@Override
public String toString() {
Expand Down Expand Up @@ -344,6 +364,11 @@ public String toString() {
if (forUpdateTable != null) {
sql.append(" OF ").append(forUpdateTable);
}

if (wait != null) {
// Wait's toString will do the formatting for us
sql.append(wait);
}
}
} else {
//without from
Expand Down Expand Up @@ -432,4 +457,4 @@ public static String getStringList(List<?> list, boolean useComma, boolean useBr

return ans.toString();
}
}
}
52 changes: 52 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/select/Wait.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* #%L JSQLParser library %% Copyright (C) 2004 - 2017 JSQLParser %% This program is free software:
* you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 2.1 of the License, or (at your
* option) any later version. This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Lesser Public License for more details. You should have
* received a copy of the GNU General Lesser Public License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>. #L%
*/
package net.sf.jsqlparser.statement.select;

/**
* A timeout applied to SELECT to specify how long to wait for the row on the
* lock to be released.
*
* @author janmonterrubio
*/
public class Wait {
private long timeout;

/**
* Returns the number of seconds specified for the WAIT command
*
* @return the number of seconds specified for the WAIT command
*/
public long getTimeout() {
return timeout;
}

/**
* Sets the number of seconds to WAIT for this {@link Wait}
*
* @param timeout
* the number of seconds to WAIT for this {@link Wait}
*/
public void setTimeout(long timeout) {
this.timeout = timeout;
}

/**
* Returns a String containing the WAIT clause and its timeout, where
* TIMEOUT is specified by {@link #getTimeout()}. The returned string will
* be:<code>
* &quot; WAIT &lt;TIMEOUT&gt;&quot;
* </code>
*/
@Override
public String toString() {
return " WAIT " + timeout;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ public void visit(PlainSelect plainSelect) {
if (plainSelect.getForUpdateTable() != null) {
buffer.append(" OF ").append(plainSelect.getForUpdateTable());
}
if (plainSelect.getWait() != null) {
// wait's toString will do the formatting for us
buffer.append(plainSelect.getWait());
}
}
if (plainSelect.isUseBrackets()) {
buffer.append(")");
Expand Down
22 changes: 20 additions & 2 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
| <K_PRECISION : "PRECISION">
| <K_TABLESPACE : "TABLESPACE">
| <K_EXCLUDE : "EXCLUDE">
| <K_WAIT : "WAIT">
}

TOKEN : /* Stuff */
Expand Down Expand Up @@ -889,6 +890,7 @@ PlainSelect PlainSelect():
OracleHierarchicalExpression oracleHierarchicalQueryClause = null;
List<Table> intoTables = null;
Table updateTable = null;
Wait wait = null;
}
{
<K_SELECT>
Expand Down Expand Up @@ -931,8 +933,9 @@ PlainSelect PlainSelect():
[LOOKAHEAD(<K_OFFSET>) offset = Offset() { plainSelect.setOffset(offset); } ]
[LOOKAHEAD(<K_FETCH>) fetch = Fetch() { plainSelect.setFetch(fetch); } ]

[ <K_FOR> <K_UPDATE> { plainSelect.setForUpdate(true); }
[ <K_OF> updateTable = Table() { plainSelect.setForUpdateTable(updateTable); } ] ]
[ <K_FOR> <K_UPDATE> { plainSelect.setForUpdate(true); }
[ <K_OF> updateTable = Table() { plainSelect.setForUpdateTable(updateTable); } ]
[ LOOKAHEAD(<K_WAIT>) wait = Wait() { plainSelect.setWait(wait); } ] ]

{
plainSelect.setSelectItems(selectItems);
Expand Down Expand Up @@ -3220,3 +3223,18 @@ Alter AlterTable():
return alter;
}
}

Wait Wait():
{
Wait wait = new Wait();
Token token = null;
}
{
// sqlserver-oracle-> WAIT (TIMEOUT)
// https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10002.htm#i2126016
<K_WAIT> token=<S_LONG> { wait.setTimeout(Long.parseLong(token.image)); }

{
return wait;
}
}
23 changes: 23 additions & 0 deletions src/test/java/net/sf/jsqlparser/test/select/SelectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,29 @@ public void testKeyWorkReplaceIssue393() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed("SELECT replace(\"aaaabbb\", 4, 4, \"****\")");
}

/**
* Validates that a SELECT with FOR UPDATE WAIT <TIMEOUT> can be parsed and
* deparsed
*/
public void testForUpdateWaitParseDeparse() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable FOR UPDATE WAIT 60");
}

/**
* Validates that a SELECT with FOR UPDATE WAIT <TIMEOUT> correctly sets a
* {@link Wait} with the correct timeout value.
*/
public void testForUpdateWaitWithTimeout() throws JSQLParserException {
String statement = "SELECT * FROM mytable FOR UPDATE WAIT 60";
Select select = (Select) parserManager.parse(new StringReader(statement));
PlainSelect ps = (PlainSelect) select.getSelectBody();
Wait wait = ps.getWait();
assertNotNull("wait should not be null", wait);

long waitTime = wait.getTimeout();
assertEquals("wait time should be 60", waitTime, 60L);
}

// public void testSubSelectFailsIssue394() throws JSQLParserException {
// assertSqlCanBeParsedAndDeparsed("select aa.* , t.* from accenter.all aa, (select a.* from pacioli.emc_plan a) t");
// }
Expand Down