|
11 | 11 |
|
12 | 12 | import net.sf.jsqlparser.JSQLParserException; |
13 | 13 | import net.sf.jsqlparser.parser.CCJSqlParserUtil; |
| 14 | +import net.sf.jsqlparser.schema.Table; |
14 | 15 | import net.sf.jsqlparser.statement.Statement; |
15 | 16 | import net.sf.jsqlparser.test.TestUtils; |
16 | 17 | import org.junit.jupiter.api.Test; |
17 | 18 |
|
| 19 | +import java.util.List; |
| 20 | + |
18 | 21 | import static org.assertj.core.api.Assertions.assertThat; |
19 | 22 |
|
20 | 23 | public class ForUpdateTest { |
@@ -145,4 +148,50 @@ void testForUpdateWait() throws JSQLParserException { |
145 | 148 | assertThat(forUpdate.getWait()).isNotNull(); |
146 | 149 | assertThat(forUpdate.getWait().getTimeout()).isEqualTo(10L); |
147 | 150 | } |
| 151 | + |
| 152 | + @Test |
| 153 | + void testPostgresMultipleLockingClausesIssue2926() throws JSQLParserException { |
| 154 | + String sqlStr = "SELECT * FROM t JOIN u ON u.t_id = t.id FOR UPDATE OF t FOR SHARE OF u"; |
| 155 | + Statement stmt = TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); |
| 156 | + PlainSelect plainSelect = (PlainSelect) stmt; |
| 157 | + |
| 158 | + assertThat(plainSelect.getForMode()).isEqualTo(ForMode.UPDATE); |
| 159 | + assertThat(plainSelect.getForUpdateTables()).extracting(Table::getName) |
| 160 | + .containsExactly("t"); |
| 161 | + |
| 162 | + assertThat(plainSelect.getAdditionalForUpdateClauses()).hasSize(1); |
| 163 | + ForUpdateClause second = plainSelect.getAdditionalForUpdateClauses().get(0); |
| 164 | + assertThat(second.isForShare()).isTrue(); |
| 165 | + assertThat(second.getTables()).extracting(Table::getName).containsExactly("u"); |
| 166 | + } |
| 167 | + |
| 168 | + @Test |
| 169 | + void testPostgresMultipleLockingClausesWithOptions() throws JSQLParserException { |
| 170 | + String sqlStr = "SELECT * FROM a, b, c, d" |
| 171 | + + " FOR NO KEY UPDATE OF a NOWAIT" |
| 172 | + + " FOR KEY SHARE OF b, c SKIP LOCKED" |
| 173 | + + " FOR SHARE" |
| 174 | + + " FOR UPDATE OF d NOWAIT"; |
| 175 | + Statement stmt = TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true); |
| 176 | + PlainSelect plainSelect = (PlainSelect) stmt; |
| 177 | + |
| 178 | + assertThat(plainSelect.getForMode()).isEqualTo(ForMode.NO_KEY_UPDATE); |
| 179 | + assertThat(plainSelect.isNoWait()).isTrue(); |
| 180 | + |
| 181 | + List<ForUpdateClause> more = plainSelect.getAdditionalForUpdateClauses(); |
| 182 | + assertThat(more).extracting(ForUpdateClause::getMode) |
| 183 | + .containsExactly(ForMode.KEY_SHARE, ForMode.SHARE, ForMode.UPDATE); |
| 184 | + assertThat(more.get(0).getTables()).extracting(Table::getName) |
| 185 | + .containsExactly("b", "c"); |
| 186 | + assertThat(more.get(0).isSkipLocked()).isTrue(); |
| 187 | + assertThat(more.get(1).getTables()).isNull(); |
| 188 | + assertThat(more.get(2).isNoWait()).isTrue(); |
| 189 | + } |
| 190 | + |
| 191 | + @Test |
| 192 | + void testSingleLockingClauseHasNoAdditionalClauses() throws JSQLParserException { |
| 193 | + PlainSelect plainSelect = |
| 194 | + (PlainSelect) CCJSqlParserUtil.parse("SELECT * FROM t FOR UPDATE OF t"); |
| 195 | + assertThat(plainSelect.getAdditionalForUpdateClauses()).isNull(); |
| 196 | + } |
148 | 197 | } |
0 commit comments