[plsql] Fix support of WITH clause

This commit is contained in:
Laurent Bovet 2024-02-15 12:41:11 +01:00
parent 9e900a2c70
commit 4509b6b966
3 changed files with 59 additions and 2 deletions

View File

@ -1279,6 +1279,7 @@ void AbstractSelectStatement(AbstractSelectStatement node) #void :
ASTSelectIntoStatement SelectIntoStatement() :
{}
{
[ WithClause() ] // Although undocumented, WITH works with SELECT INTO !
AbstractSelectStatement(jjtThis)
SelectList()
( IntoClause() | BulkCollectIntoClause() )
@ -2330,11 +2331,11 @@ ASTUnlabelledStatement UnlabelledStatement() :
{}
{
(
// small optimization: SelectIntoStatement and SelectStatement both begin with SELECT
// small optimization: SelectIntoStatement and SelectStatement both begin with WITH or SELECT
// but to distinguish the two, a complete lookahead of SelectIntoStatement needs to be parsed.
// Using a lookahead of a single token first avoids this the syntatic lookahead for all other choices
// not related to SELECT statements.
LOOKAHEAD(<SELECT>) (
LOOKAHEAD(<WITH>|<SELECT>) (
LOOKAHEAD(SelectIntoStatement()) SelectIntoStatement() ";" |
SelectStatement() ";"
) |

View File

@ -0,0 +1,39 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.plsql.ast;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.util.List;
import org.junit.jupiter.api.Test;
import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst;
class WithClauseTest extends AbstractPLSQLParserTst {
@Test
void testSelect() {
ASTInput input = plsql.parseResource("WithClause.pls");
List<ASTSelectStatement> selectStatements = input.descendants(ASTSelectStatement.class).toList();
assertEquals(1, selectStatements.size());
assertNotNull(selectStatements.get(0).descendants(ASTWithClause.class).first());
assertNotNull(selectStatements.get(0).descendants(ASTSelectList.class).first());
}
@Test
void testSelectInto() {
ASTInput input = plsql.parseResource("WithClause.pls");
List<ASTSelectIntoStatement> selectStatements = input.descendants(ASTSelectIntoStatement.class).toList();
assertEquals(1, selectStatements.size());
assertNotNull(selectStatements.get(0).descendants(ASTWithClause.class).first());
assertNotNull(selectStatements.get(0).descendants(ASTSelectList.class).first());
}
}

View File

@ -0,0 +1,17 @@
--
-- WITH Clause
--
BEGIN
WITH titles as ( SELECT * FROM academic_titles )
SELECT adt.adt_id
FROM titles adt;
WITH titles as ( SELECT * FROM academic_titles )
SELECT adt.adt_id
INTO v_adt_id
FROM titles adt;
END;
/